summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Schlomoff <gregschlom@google.com>2022-07-19 17:01:07 -0700
committerGreg Schlomoff <gregschlom@google.com>2022-10-04 16:32:21 -0700
commit4f12c1042403cac665686e57f4dafec82656fa25 (patch)
tree173d083b79709f30729261ff58e070424587d554
parent8456d5a83ab432c1d35aeb4d1606afb6b70d7dce (diff)
downloadvulkan-cereal-4f12c1042403cac665686e57f4dafec82656fa25.tar.gz
Remove our old ASTC decoder and replace it with Arm's one.
Change-Id: Icb49eb5ccfb31d4bf5a352e36dcad77dcde101d8
-rw-r--r--stream-servers/Android.bp1
-rw-r--r--stream-servers/gl/glestranslator/EGL/Android.bp1
-rw-r--r--stream-servers/gl/glestranslator/EGL/CMakeLists.txt2
-rw-r--r--stream-servers/gl/glestranslator/GLcommon/Android.bp4
-rw-r--r--stream-servers/gl/glestranslator/GLcommon/CMakeLists.txt2
-rw-r--r--stream-servers/gl/glestranslator/GLcommon/TextureUtils.cpp110
-rw-r--r--third-party/CMakeLists.txt3
-rw-r--r--third-party/astc-codec/.gitignore5
-rw-r--r--third-party/astc-codec/Android.bp25
-rw-r--r--third-party/astc-codec/BUILD.bazel28
-rw-r--r--third-party/astc-codec/CMakeLists.txt46
-rw-r--r--third-party/astc-codec/CONTRIBUTING.md28
-rw-r--r--third-party/astc-codec/GoogleTest-CMakeLists.txt.in15
-rw-r--r--third-party/astc-codec/LICENSE202
-rw-r--r--third-party/astc-codec/README.md71
-rw-r--r--third-party/astc-codec/WORKSPACE34
-rw-r--r--third-party/astc-codec/cmake-format.json38
-rw-r--r--third-party/astc-codec/include/astc-codec/astc-codec.h75
-rw-r--r--third-party/astc-codec/src/.clang-format4
-rw-r--r--third-party/astc-codec/src/base/BUILD.bazel46
-rw-r--r--third-party/astc-codec/src/base/CMakeLists.txt27
-rw-r--r--third-party/astc-codec/src/base/bit_stream.h77
-rw-r--r--third-party/astc-codec/src/base/bottom_n.h78
-rw-r--r--third-party/astc-codec/src/base/math_utils.h80
-rw-r--r--third-party/astc-codec/src/base/optional.h520
-rw-r--r--third-party/astc-codec/src/base/string_utils.h68
-rw-r--r--third-party/astc-codec/src/base/test/bit_stream_test.cpp141
-rw-r--r--third-party/astc-codec/src/base/test/bottom_n_test.cpp108
-rw-r--r--third-party/astc-codec/src/base/test/math_utils_test.cpp78
-rw-r--r--third-party/astc-codec/src/base/test/optional_test.cpp481
-rw-r--r--third-party/astc-codec/src/base/test/string_utils_test.cpp110
-rw-r--r--third-party/astc-codec/src/base/test/type_traits_test.cpp130
-rw-r--r--third-party/astc-codec/src/base/test/uint128_test.cpp140
-rw-r--r--third-party/astc-codec/src/base/type_traits.h172
-rw-r--r--third-party/astc-codec/src/base/uint128.h175
-rw-r--r--third-party/astc-codec/src/base/utils.h35
-rw-r--r--third-party/astc-codec/src/decoder/Android.bp29
-rw-r--r--third-party/astc-codec/src/decoder/BUILD.bazel238
-rw-r--r--third-party/astc-codec/src/decoder/CMakeLists.txt95
-rw-r--r--third-party/astc-codec/src/decoder/astc_file.cc185
-rw-r--r--third-party/astc-codec/src/decoder/astc_file.h97
-rw-r--r--third-party/astc-codec/src/decoder/codec.cc132
-rw-r--r--third-party/astc-codec/src/decoder/codec.h41
-rw-r--r--third-party/astc-codec/src/decoder/endpoint_codec.cc967
-rw-r--r--third-party/astc-codec/src/decoder/endpoint_codec.h90
-rw-r--r--third-party/astc-codec/src/decoder/footprint.cc162
-rw-r--r--third-party/astc-codec/src/decoder/footprint.h106
-rw-r--r--third-party/astc-codec/src/decoder/integer_sequence_codec.cc570
-rw-r--r--third-party/astc-codec/src/decoder/integer_sequence_codec.h169
-rw-r--r--third-party/astc-codec/src/decoder/intermediate_astc_block.cc591
-rw-r--r--third-party/astc-codec/src/decoder/intermediate_astc_block.h128
-rw-r--r--third-party/astc-codec/src/decoder/logical_astc_block.cc262
-rw-r--r--third-party/astc-codec/src/decoder/logical_astc_block.h127
-rw-r--r--third-party/astc-codec/src/decoder/partition.cc601
-rw-r--r--third-party/astc-codec/src/decoder/partition.h97
-rw-r--r--third-party/astc-codec/src/decoder/physical_astc_block.cc761
-rw-r--r--third-party/astc-codec/src/decoder/physical_astc_block.h128
-rw-r--r--third-party/astc-codec/src/decoder/quantization.cc462
-rw-r--r--third-party/astc-codec/src/decoder/quantization.h65
-rw-r--r--third-party/astc-codec/src/decoder/test/astc_fuzzer.cc36
-rw-r--r--third-party/astc-codec/src/decoder/test/codec_test.cc181
-rw-r--r--third-party/astc-codec/src/decoder/test/endpoint_codec_test.cc463
-rw-r--r--third-party/astc-codec/src/decoder/test/footprint_test.cc97
-rw-r--r--third-party/astc-codec/src/decoder/test/image_utils.h217
-rw-r--r--third-party/astc-codec/src/decoder/test/integer_sequence_codec_test.cc336
-rw-r--r--third-party/astc-codec/src/decoder/test/intermediate_astc_block_test.cc454
-rw-r--r--third-party/astc-codec/src/decoder/test/logical_astc_block_test.cc273
-rw-r--r--third-party/astc-codec/src/decoder/test/partition_test.cc263
-rw-r--r--third-party/astc-codec/src/decoder/test/physical_astc_block_test.cc361
-rw-r--r--third-party/astc-codec/src/decoder/test/quantization_test.cc288
-rw-r--r--third-party/astc-codec/src/decoder/test/weight_infill_test.cc69
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.astcbin65552 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.bmpbin262282 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.astcbin43280 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.bmpbin262282 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.astcbin29600 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.bmpbin262282 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.astcbin16400 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.bmpbin262282 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkerboard.astcbin80 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_10.astcbin1616 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_11.astcbin1952 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_12.astcbin2320 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_4.astcbin272 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_5.astcbin416 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_6.astcbin592 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_7.astcbin800 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_8.astcbin1040 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/checkered_9.astcbin1312 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x10.astcbin272 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x10.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x5.astcbin464 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x5.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x6.astcbin400 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x6.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x8.astcbin272 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_10x8.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_12x10.astcbin208 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_12x10.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_12x12.astcbin160 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_12x12.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_4x4.astcbin1040 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_4x4.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_5x4.astcbin912 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_5x4.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_5x5.astcbin800 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_5x5.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_6x5.astcbin688 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_6x5.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_6x6.astcbin592 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_6x6.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_8x5.astcbin464 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_8x5.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_8x6.astcbin400 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_8x6.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_8x8.astcbin272 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/footprint_8x8.bmpbin3210 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_12x12.astcbin7312 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_12x12.bmpbin193674 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_4x4.astcbin64528 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_4x4.bmpbin193674 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_5x4.astcbin51856 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_5x4.bmpbin193674 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_6x6.astcbin29200 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_6x6.bmpbin193674 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_8x8.astcbin16144 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/testdata/rgb_8x8.bmpbin193674 -> 0 bytes
-rw-r--r--third-party/astc-codec/src/decoder/tools/astc_inspector_cli.cc785
-rw-r--r--third-party/astc-codec/src/decoder/types.h74
-rw-r--r--third-party/astc-codec/src/decoder/weight_infill.cc122
-rw-r--r--third-party/astc-codec/src/decoder/weight_infill.h38
-rw-r--r--third-party/astc-codec/third_party/honggfuzz.BUILD34
-rw-r--r--third-party/astc-codec/tools/bazel.rc6
133 files changed, 58 insertions, 13302 deletions
diff --git a/stream-servers/Android.bp b/stream-servers/Android.bp
index 13d418cd..2484f6a7 100644
--- a/stream-servers/Android.bp
+++ b/stream-servers/Android.bp
@@ -43,7 +43,6 @@ cc_library_shared {
"gfxstream_vulkan_server",
"gfxstream_renderControl_dec",
"gfxstream_dispatch",
- "gfxstream_astc_codec",
"gfxstream_lz4",
"gfxstream_glm",
"gfxstream_compressedTextures",
diff --git a/stream-servers/gl/glestranslator/EGL/Android.bp b/stream-servers/gl/glestranslator/EGL/Android.bp
index 6275c628..037c37c8 100644
--- a/stream-servers/gl/glestranslator/EGL/Android.bp
+++ b/stream-servers/gl/glestranslator/EGL/Android.bp
@@ -12,7 +12,6 @@ cc_library_static {
defaults: [ "gfxstream_defaults" ],
static_libs: [
"gfxstream_base",
- "gfxstream_astc_codec",
"gfxstream_apigen_codec_common",
"gfxstream_translator_glcommon",
"gfxstream_translator_glescm",
diff --git a/stream-servers/gl/glestranslator/EGL/CMakeLists.txt b/stream-servers/gl/glestranslator/EGL/CMakeLists.txt
index 654f55d0..5033a63d 100644
--- a/stream-servers/gl/glestranslator/EGL/CMakeLists.txt
+++ b/stream-servers/gl/glestranslator/EGL/CMakeLists.txt
@@ -38,7 +38,7 @@ else()
endif()
target_link_libraries(EGL_translator_static PUBLIC GLcommon apigen-codec-common)
-target_link_libraries(EGL_translator_static PRIVATE gfxstream-base.headers astc-codec logging-base)
+target_link_libraries(EGL_translator_static PRIVATE gfxstream-base.headers logging-base)
target_link_libraries(EGL_translator_static PUBLIC GLES_CM_translator_static GLES_V2_translator_static)
if (NOT MSVC)
target_compile_options(EGL_translator_static PRIVATE -fvisibility=hidden)
diff --git a/stream-servers/gl/glestranslator/GLcommon/Android.bp b/stream-servers/gl/glestranslator/GLcommon/Android.bp
index 91be25d5..d07f8d38 100644
--- a/stream-servers/gl/glestranslator/GLcommon/Android.bp
+++ b/stream-servers/gl/glestranslator/GLcommon/Android.bp
@@ -16,12 +16,8 @@ cc_library_static {
"-Wno-unused-parameter",
"-Wno-unused-function",
],
- header_libs: [
- "gfxstream_astc_codec_headers",
- ],
static_libs: [
"gfxstream_base",
- "gfxstream_astc_codec",
],
srcs: [
"etc.cpp",
diff --git a/stream-servers/gl/glestranslator/GLcommon/CMakeLists.txt b/stream-servers/gl/glestranslator/GLcommon/CMakeLists.txt
index 8ccaf0a7..e7701179 100644
--- a/stream-servers/gl/glestranslator/GLcommon/CMakeLists.txt
+++ b/stream-servers/gl/glestranslator/GLcommon/CMakeLists.txt
@@ -32,7 +32,7 @@ target_link_libraries(
gfxstream-base.headers
gfxstream-host-common.headers
gfxstream-snapshot.headers
- astc-codec)
+ gfxstream-compressedTextures)
if (NOT MSVC)
target_compile_options(GLcommon PRIVATE -fvisibility=hidden)
endif()
diff --git a/stream-servers/gl/glestranslator/GLcommon/TextureUtils.cpp b/stream-servers/gl/glestranslator/GLcommon/TextureUtils.cpp
index a66338bd..aa4c4129 100644
--- a/stream-servers/gl/glestranslator/GLcommon/TextureUtils.cpp
+++ b/stream-servers/gl/glestranslator/GLcommon/TextureUtils.cpp
@@ -22,10 +22,10 @@
#include <memory>
#include "base/AlignedBuf.h"
-
-#include <astc-codec/astc-codec.h>
+#include "compressedTextureFormats/AstcCpuDecompressor.h"
using android::AlignedBuf;
+using goldfish_vk::AstcCpuDecompressor;
#define GL_R16 0x822A
#define GL_RG16 0x822C
@@ -35,34 +35,34 @@ using android::AlignedBuf;
static constexpr size_t kASTCFormatsCount = 28;
#define ASTC_FORMATS_LIST(EXPAND_MACRO) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, astc_codec::FootprintType::k4x4, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, astc_codec::FootprintType::k5x4, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, astc_codec::FootprintType::k5x5, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, astc_codec::FootprintType::k6x5, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, astc_codec::FootprintType::k6x6, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, astc_codec::FootprintType::k8x5, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, astc_codec::FootprintType::k8x6, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, astc_codec::FootprintType::k8x8, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, astc_codec::FootprintType::k10x5, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, astc_codec::FootprintType::k10x6, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, astc_codec::FootprintType::k10x8, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, astc_codec::FootprintType::k10x10, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, astc_codec::FootprintType::k12x10, false) \
- EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, astc_codec::FootprintType::k12x12, false) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, astc_codec::FootprintType::k4x4, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, astc_codec::FootprintType::k5x4, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, astc_codec::FootprintType::k5x5, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, astc_codec::FootprintType::k6x5, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, astc_codec::FootprintType::k6x6, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, astc_codec::FootprintType::k8x5, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, astc_codec::FootprintType::k8x6, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, astc_codec::FootprintType::k8x8, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, astc_codec::FootprintType::k10x5, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, astc_codec::FootprintType::k10x6, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, astc_codec::FootprintType::k10x8, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, astc_codec::FootprintType::k10x10, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, astc_codec::FootprintType::k12x10, true) \
- EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, astc_codec::FootprintType::k12x12, true) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 4, 4, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 5, 4, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 5, 5, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 6, 5, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 6, 6, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 8, 5, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 8, 6, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 8, 8, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 10, 5, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 10, 6, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 10, 8, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 10, 10, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 12, 10, false) \
+ EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 12, 12, false) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 4, 4, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 5, 4, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 5, 5, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 6, 5, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 6, 6, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 8, 5, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 8, 6, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 8, 8, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 10, 5, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 10, 6, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 10, 8, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 10, 10, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 12, 10, true) \
+ EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 12, 12, true) \
int getCompressedFormats(int majorVersion, int* formats) {
static constexpr size_t kCount = MAX_SUPPORTED_PALETTE + MAX_ETC_SUPPORTED + kASTCFormatsCount;
@@ -104,7 +104,7 @@ int getCompressedFormats(int majorVersion, int* formats) {
formats[i++] = GL_COMPRESSED_R11_EAC;
// ASTC
-#define ASTC_FORMAT(typeName, footprintType, srgbValue) \
+#define ASTC_FORMAT(typeName, blockWidth, blockHeight, srgbValue) \
formats[i++] = typeName;
ASTC_FORMATS_LIST(ASTC_FORMAT)
@@ -151,13 +151,11 @@ ETC2ImageFormat getEtcFormat(GLenum internalformat) {
return etcFormat;
}
-void getAstcFormatInfo(GLenum internalformat,
- astc_codec::FootprintType* footprint,
- bool* srgb) {
+void getAstcFormatInfo(GLenum internalformat, uint32_t* width, uint32_t* height, bool* srgb) {
switch (internalformat) {
-#define ASTC_FORMAT(typeName, footprintType, srgbValue) \
+#define ASTC_FORMAT(typeName, blockWidth, blockHeight, srgbValue) \
case typeName: \
- *footprint = footprintType; *srgb = srgbValue; break; \
+ *width = blockWidth; *height = blockHeight; *srgb = srgbValue; break; \
ASTC_FORMATS_LIST(ASTC_FORMAT)
#undef ASTC_FORMAT
@@ -167,22 +165,26 @@ void getAstcFormatInfo(GLenum internalformat,
}
}
-void getAstcFormats(const GLint** formats, size_t* formatsCount) {
- static constexpr GLint kATSCFormats[] = {
-#define ASTC_FORMAT(typeName, footprintType, srgbValue) \
- typeName,
-
- ASTC_FORMATS_LIST(ASTC_FORMAT)
-#undef ASTC_FORMAT
- };
-
- *formats = kATSCFormats;
- *formatsCount = sizeof(kATSCFormats) / sizeof(kATSCFormats[0]);
+// Helper function to decompress an ASTC image.
+bool astcDecompress(const uint8_t* astcData, size_t astcDataSize, uint32_t width, uint32_t height,
+ uint32_t blockWidth, uint32_t blockHeight, uint8_t* outBuffer,
+ size_t outBufferSize) {
+ if (outBufferSize < width * height * 4) {
+ WARN("ASTC output buffer too small: %d bytes for %d x %d", outBufferSize, width, height);
+ return false;
+ }
+ int32_t status = AstcCpuDecompressor::get().decompress(width, height, blockWidth, blockHeight,
+ astcData, astcDataSize, outBuffer);
+ if (status != 0) {
+ WARN("astc decompression failed: %s", AstcCpuDecompressor::get().getStatusString(status));
+ return false;
+ }
+ return true;
}
bool isAstcFormat(GLenum internalformat) {
switch (internalformat) {
-#define ASTC_FORMAT(typeName, footprintType, srgbValue) \
+#define ASTC_FORMAT(typeName, blockWidth, blockHeight, srgbValue) \
case typeName:
ASTC_FORMATS_LIST(ASTC_FORMAT)
@@ -505,9 +507,10 @@ void doCompressedTexImage2D(GLEScontext* ctx, GLenum target, GLint level,
data = new char[imageSize];
}
}
- astc_codec::FootprintType footprint;
+ uint32_t blockWidth = 0;
+ uint32_t blockHeight = 0;
bool srgb;
- getAstcFormatInfo(internalformat, &footprint, &srgb);
+ getAstcFormatInfo(internalformat, &blockWidth, &blockHeight, &srgb);
const int32_t align = unpackAlignment - 1;
const int32_t stride = ((width * 4) + align) & ~align;
@@ -515,10 +518,9 @@ void doCompressedTexImage2D(GLEScontext* ctx, GLenum target, GLint level,
AlignedBuf<uint8_t, 64> alignedUncompressedData(size);
- const bool result = astc_codec::ASTCDecompressToRGBA(
+ const bool result = astcDecompress(
reinterpret_cast<const uint8_t*>(data), imageSize, width,
- height, footprint, alignedUncompressedData.data(), size,
- stride);
+ height, blockWidth, blockHeight, alignedUncompressedData.data(), size);
SET_ERROR_IF(!result, GL_INVALID_VALUE);
glTexImage2DPtr(target, level, srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8, width,
@@ -846,7 +848,7 @@ void forEachEtc2Format(std::function<void(GLint format)> f) {
void forEachAstcFormat(std::function<void(GLint format)> f) {
-#define CALL_ON_ASTC_FORMAT(typeName, footprintType, srgbValue) \
+#define CALL_ON_ASTC_FORMAT(typeName, blockWidth, blockHeight, srgbValue) \
f(typeName);
ASTC_FORMATS_LIST(CALL_ON_ASTC_FORMAT)
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index 354d7a37..ceffa629 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -1,8 +1,5 @@
add_subdirectory(angle)
-# TODO(gregschlom) Remove this in favor of astc-encoder
-add_subdirectory(astc-codec)
-
# Configure and add `astc-encoder`, if needed
if (ASTC_CPU_DECODING)
set(DECOMPRESSOR ON) # Disable compression code
diff --git a/third-party/astc-codec/.gitignore b/third-party/astc-codec/.gitignore
deleted file mode 100644
index 9e281007..00000000
--- a/third-party/astc-codec/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-bazel-*
-.bazelrc
-build
-.vs
-.vscode
diff --git a/third-party/astc-codec/Android.bp b/third-party/astc-codec/Android.bp
deleted file mode 100644
index 02a9456d..00000000
--- a/third-party/astc-codec/Android.bp
+++ /dev/null
@@ -1,25 +0,0 @@
-package {
- default_applicable_licenses: [
- "device_generic_vulkan-cereal_third-party_astc-codec_license",
- ],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
- name: "device_generic_vulkan-cereal_third-party_astc-codec_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- ],
- license_text: [
- "LICENSE",
- ],
-}
-
-cc_library_headers {
- name: "gfxstream_astc_codec_headers",
- defaults: ["gfxstream_defaults"],
- host_supported: true,
- export_include_dirs: [ ".", "include" ],
-}
diff --git a/third-party/astc-codec/BUILD.bazel b/third-party/astc-codec/BUILD.bazel
deleted file mode 100644
index 8fc9eca4..00000000
--- a/third-party/astc-codec/BUILD.bazel
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-licenses(["notice"])
-
-cc_library(
- name = "api",
- hdrs = ["include/astc-codec/astc-codec.h"],
- visibility = ["//src/decoder:__pkg__"],
-)
-
-cc_library(
- name = "astc_codec",
- deps = ["//src/decoder:codec"],
- includes = ["include"],
- visibility = ["//visibility:public"],
-)
diff --git a/third-party/astc-codec/CMakeLists.txt b/third-party/astc-codec/CMakeLists.txt
deleted file mode 100644
index 4670d9a8..00000000
--- a/third-party/astc-codec/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
-# use this file except in compliance with the License. You may obtain a copy of
-# the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations under
-# the License.
-cmake_minimum_required(VERSION 3.1.0)
-project(astc-codec)
-
-option(OPTION_ASTC_TESTS "Build all the unit tests." OFF)
-
-# TODO add support for the fuzzer, it has some additional dependencies we are not
-# yet bringing in.
-option(OPTION_BUILD_FUZZER "Build the fuzzer tests." OFF)
-
-set (CMAKE_CXX_STANDARD 11)
-if(OPTION_ASTC_TESTS)
- enable_testing()
-
- # No need to build gmock if an external project defines it.
- if(NOT TARGET gmock_main)
- # We use the approach suggested by https://crascit.com/2015/07/25/cmake-gtest/ to download gtest.
- include(ExternalProject)
- # Download and unpack googletest at configure time
- configure_file(GoogleTest-CMakeLists.txt.in googletest-download/CMakeLists.txt)
- execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download")
- execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download")
-
- # Prevent GoogleTest from overriding our compiler/linker options when building with Visual Studio
- set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
-
- # Add googletest directly to our build. This adds the following targets: gtest, gtest_main, gmock and gmock_main
- add_subdirectory("${CMAKE_BINARY_DIR}/googletest-src" "${CMAKE_BINARY_DIR}/googletest-build")
- endif()
-endif()
-
-add_subdirectory(src/base)
-add_subdirectory(src/decoder)
diff --git a/third-party/astc-codec/CONTRIBUTING.md b/third-party/astc-codec/CONTRIBUTING.md
deleted file mode 100644
index 939e5341..00000000
--- a/third-party/astc-codec/CONTRIBUTING.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# How to Contribute
-
-We'd love to accept your patches and contributions to this project. There are
-just a few small guidelines you need to follow.
-
-## Contributor License Agreement
-
-Contributions to this project must be accompanied by a Contributor License
-Agreement. You (or your employer) retain the copyright to your contribution;
-this simply gives us permission to use and redistribute your contributions as
-part of the project. Head over to <https://cla.developers.google.com/> to see
-your current agreements on file or to sign a new one.
-
-You generally only need to submit a CLA once, so if you've already submitted one
-(even if it was for a different project), you probably don't need to do it
-again.
-
-## Code reviews
-
-All submissions, including submissions by project members, require review. We
-use GitHub pull requests for this purpose. Consult
-[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
-information on using pull requests.
-
-## Community Guidelines
-
-This project follows [Google's Open Source Community
-Guidelines](https://opensource.google.com/conduct/).
diff --git a/third-party/astc-codec/GoogleTest-CMakeLists.txt.in b/third-party/astc-codec/GoogleTest-CMakeLists.txt.in
deleted file mode 100644
index 569f4dfb..00000000
--- a/third-party/astc-codec/GoogleTest-CMakeLists.txt.in
+++ /dev/null
@@ -1,15 +0,0 @@
-cmake_minimum_required(VERSION 2.8.2)
-
-project(googletest-download NONE)
-
-include(ExternalProject)
-ExternalProject_Add(googletest
- GIT_REPOSITORY https://github.com/google/googletest.git
- GIT_TAG "release-1.8.1"
- SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- TEST_COMMAND ""
-) \ No newline at end of file
diff --git a/third-party/astc-codec/LICENSE b/third-party/astc-codec/LICENSE
deleted file mode 100644
index d6456956..00000000
--- a/third-party/astc-codec/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/third-party/astc-codec/README.md b/third-party/astc-codec/README.md
deleted file mode 100644
index 8bb2c269..00000000
--- a/third-party/astc-codec/README.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# astc-codec
-
-astc-codec is a software ASTC decoder implementation, which supports the ASTC
-LDR profile.
-
-Example usage:
-
-```
-#include <astc-codec/astc-codec.h>
-
-// ...
-
-std::vector<uint8_t> astc = LoadMyASTCData();
-const size_t width = 640;
-const size_t height = 480;
-
-std::vector<uint8_t> result;
-result.resize(width * height * 4);
-
-bool result = astc_codec::ASTCDecompressToRGBA(
- astc.data(), astc.size(), width, height, astc_codec::FootprintType::k4x4,
- result.data(), result.size(), /* stride */ width * 4);
-```
-
-## Building
-
-### With bazel
-
-Install [Bazel](https://bazel.build/), and then run:
-
-```
-bazel build :astc_codec -c opt
-```
-
-astc-codec has been tested on Mac and Linux.
-
-### Run Tests
-
-```
-bazel test //...
-```
-
-### With CMake
-
-Install [CMake](https://https://cmake.org/), and the run:
-
-```
-mkdir build && cd build && cmake .. && make
-```
-
-Or open the project in your favorite IDE and import CMakeLists.txt.
-
-### Run Tests
-
-In the build directory, execute:
-
-```
-ctest
-```
-
-
-## Contributing
-
-See [CONTRIBUTING.md](CONTRIBUTING.md) for important contributing requirements.
-
-## License
-
-astc-codec project is licensed under the Apache License Version 2.0. You can
-find a copy of it in [LICENSE](LICENSE).
-
-This is not an officially supported Google product.
diff --git a/third-party/astc-codec/WORKSPACE b/third-party/astc-codec/WORKSPACE
deleted file mode 100644
index 77d6a692..00000000
--- a/third-party/astc-codec/WORKSPACE
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-git_repository(
- name = "gtest",
- remote = "https://github.com/google/googletest.git",
- commit = "ba96d0b1161f540656efdaed035b3c062b60e006",
-)
-
-new_http_archive(
- name = "honggfuzz",
- url = "https://github.com/google/honggfuzz/archive/1.6.zip",
- sha256 = "c331ac5beebe526bced3043ed3012109e439315b7d74d72760b0aa6d08cc05d2",
- build_file = "third_party/honggfuzz.BUILD",
- strip_prefix = "honggfuzz-1.6",
-)
-
-http_archive(
- name = "benchmark",
- url = "https://github.com/google/benchmark/archive/v1.4.1.zip",
- sha256 = "61ae07eb5d4a0b02753419eb17a82b7d322786bb36ab62bd3df331a4d47c00a7",
- strip_prefix = "benchmark-1.4.1",
-)
diff --git a/third-party/astc-codec/cmake-format.json b/third-party/astc-codec/cmake-format.json
deleted file mode 100644
index de38ed28..00000000
--- a/third-party/astc-codec/cmake-format.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "line_width": 120,
- "dangle_parens": false,
- "first_comment_is_literal": true,
- "algorithm_order": [
- 0,
- 1,
- 2,
- 3
- ],
- "command_case": "lower",
- "additional_commands": {
- "foo": {
- "flags": [
- "BAR",
- "BAZ"
- ],
- "kwargs": {
- "HEADERS": "*",
- "DEPENDS": "*",
- "SOURCES": "*"
- }
- }
- },
- "separate_fn_name_with_space": false,
- "always_wrap": [],
- "separate_ctrl_name_with_space": false,
- "max_subargs_per_line": 5,
- "fence_pattern": "^\\s*([`~]{3}[`~]*)(.*)$",
- "enable_markup": true,
- "ruler_pattern": "^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$",
- "tab_size": 2,
- "keyword_case": "unchanged",
- "enum_char": ".",
- "literal_comment_pattern": null,
- "bullet_char": "*",
- "line_ending": "unix"
-}
diff --git a/third-party/astc-codec/include/astc-codec/astc-codec.h b/third-party/astc-codec/include/astc-codec/astc-codec.h
deleted file mode 100644
index 1d412181..00000000
--- a/third-party/astc-codec/include/astc-codec/astc-codec.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_ASTC_CODEC_H_
-#define ASTC_CODEC_ASTC_CODEC_H_
-
-#include <cstddef>
-#include <cstdint>
-
-namespace astc_codec {
-
-// These are the valid ASTC footprints according to the specification in
-// Section C.2.7.
-enum class FootprintType {
- k4x4,
- k5x4,
- k5x5,
- k6x5,
- k6x6,
- k8x5,
- k8x6,
- k10x5,
- k10x6,
- k8x8,
- k10x8,
- k10x10,
- k12x10,
- k12x12,
-
- kCount
-};
-
-// Decompresses ASTC LDR image data to a RGBA32 buffer.
-//
-// Supports formats defined in the KHR_texture_compression_astc_ldr spec and
-// returns UNORM8 values. sRGB is not supported, and should be implemented
-// by the caller.
-//
-// |astc_data| - Compressed ASTC image buffer, must be at least |astc_data_size|
-// bytes long.
-// |astc_data_size| - The size of |astc_data|, in bytes.
-// |width| - Image width, in pixels.
-// |height| - Image height, in pixels.
-// |footprint| - The ASTC footprint (block size) of the compressed image buffer.
-// |out_buffer| - Pointer to a buffer where the decompressed image will be
-// stored, must be at least |out_buffer_size| bytes long.
-// |out_buffer_size| - The size of |out_buffer|, in bytes, at least
-// height*out_buffer_stride. If this is too small, this
-// function will return false and no data will be
-// decompressed.
-// |out_buffer_stride| - The stride that should be used to store rows of the
-// decoded image, must be at least 4*width bytes.
-//
-// Returns true if the decompression succeeded, or false if decompression
-// failed, or if the astc_data_size was too small for the given width, height,
-// and footprint, or if out_buffer_size is too small.
-bool ASTCDecompressToRGBA(const uint8_t* astc_data, size_t astc_data_size,
- size_t width, size_t height, FootprintType footprint,
- uint8_t* out_buffer, size_t out_buffer_size,
- size_t out_buffer_stride);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_ASTC_CODEC_H_
diff --git a/third-party/astc-codec/src/.clang-format b/third-party/astc-codec/src/.clang-format
deleted file mode 100644
index 9a00ee25..00000000
--- a/third-party/astc-codec/src/.clang-format
+++ /dev/null
@@ -1,4 +0,0 @@
-BasedOnStyle: Google
-AllowShortCaseLabelsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: Inline
-SpaceAfterTemplateKeyword: false
diff --git a/third-party/astc-codec/src/base/BUILD.bazel b/third-party/astc-codec/src/base/BUILD.bazel
deleted file mode 100644
index 09f723d7..00000000
--- a/third-party/astc-codec/src/base/BUILD.bazel
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-cc_library(
- name = "base",
- hdrs = [
- "bit_stream.h",
- "bottom_n.h",
- "math_utils.h",
- "optional.h",
- "string_utils.h",
- "type_traits.h",
- "uint128.h",
- "utils.h",
- ],
- visibility = ["//src/decoder:__pkg__"],
-)
-
-cc_test(
- name = "base_test",
- srcs = [
- "test/bit_stream_test.cpp",
- "test/bottom_n_test.cpp",
- "test/math_utils_test.cpp",
- "test/optional_test.cpp",
- "test/string_utils_test.cpp",
- "test/type_traits_test.cpp",
- "test/uint128_test.cpp",
- ],
- deps = [
- "@gtest//:gtest_main",
- ":base",
- ],
-)
-
diff --git a/third-party/astc-codec/src/base/CMakeLists.txt b/third-party/astc-codec/src/base/CMakeLists.txt
deleted file mode 100644
index 5a45f857..00000000
--- a/third-party/astc-codec/src/base/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License Version 2.0 (the License); you may not use
-# this file except in compliance with the License. You may obtain a copy of the
-# License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing software distributed
-# under the License is distributed on an AS IS BASIS WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-add_library(base INTERFACE)
-target_include_directories(base INTERFACE ../..)
-
-if(OPTION_ASTC_TESTS)
- add_executable(base_test
- test/bit_stream_test.cpp
- test/bottom_n_test.cpp
- test/math_utils_test.cpp
- test/optional_test.cpp
- test/string_utils_test.cpp
- test/type_traits_test.cpp
- test/uint128_test.cpp)
- target_link_libraries(base_test base gmock_main)
- add_test(NAME base_test COMMAND base_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
-endif()
diff --git a/third-party/astc-codec/src/base/bit_stream.h b/third-party/astc-codec/src/base/bit_stream.h
deleted file mode 100644
index 2cda0937..00000000
--- a/third-party/astc-codec/src/base/bit_stream.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_BIT_STREAM_H_
-#define ASTC_CODEC_BASE_BIT_STREAM_H_
-
-#include <cassert>
-#include <cstdint>
-
-namespace astc_codec {
-namespace base {
-
-// Represents a stream of bits that can be read or written in arbitrary-sized
-// chunks.
-template<typename IntType = uint64_t>
-class BitStream {
- public:
- // Creates an empty BitStream.
- BitStream() = default;
- BitStream(IntType data, uint32_t data_size)
- : data_(data), data_size_(data_size) {
- assert(data_size_ <= sizeof(data_) * 8);
- }
-
- // Return the number of bits in the stream.
- uint32_t Bits() const { return data_size_; }
-
- // Put |size| bits into the stream.
- // Fails if there is not enough space in the buffer to store the bits.
- template<typename ResultType>
- void PutBits(ResultType x, uint32_t size) {
- assert(data_size_ + size <= sizeof(data_) * 8);
-
- data_ |= (IntType(x) & MaskFor(size)) << data_size_;
- data_size_ += size;
- }
-
- // Get |count| bits from the stream.
- // Returns true if |count| bits were successfully retrieved.
- template<typename ResultType>
- bool GetBits(uint32_t count, ResultType* result) {
- if (count <= data_size_) {
- *result = static_cast<ResultType>(data_ & MaskFor(count));
- data_ = data_ >> count;
- data_size_ -= count;
- return true;
- } else {
- *result = ResultType();
- return false;
- }
- }
-
- private:
- IntType MaskFor(uint32_t bits) const {
- return (bits == sizeof(IntType) * 8) ? ~IntType(0)
- : (IntType(1) << bits) - 1;
- }
-
- IntType data_ = IntType();
- uint32_t data_size_ = 0;
-};
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_BIT_STREAM_H_
diff --git a/third-party/astc-codec/src/base/bottom_n.h b/third-party/astc-codec/src/base/bottom_n.h
deleted file mode 100644
index 4edc8efb..00000000
--- a/third-party/astc-codec/src/base/bottom_n.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_BOTTOM_N_H_
-#define ASTC_CODEC_BASE_BOTTOM_N_H_
-
-#include <algorithm>
-#include <functional>
-#include <vector>
-
-namespace astc_codec {
-namespace base {
-
-// Used to aggregate the lowest N values of data supplied.
-template<typename T, typename CompareFn = std::less<T>>
-class BottomN {
- public:
- typedef std::vector<T> ContainerType;
-
- // Creates an empty BottomN with limit |max_size|.
- BottomN(size_t max_size) : max_size_(max_size) { }
-
- bool Empty() const { return data_.empty(); }
- size_t Size() const { return data_.size(); }
-
- const T& Top() const { return data_.front(); }
-
- void Push(const T& value) {
- if (data_.size() < max_size_ || compare_(value, Top())) {
- data_.push_back(value);
- std::push_heap(data_.begin(), data_.end(), compare_);
-
- if (Size() > max_size_) {
- PopTop();
- }
- }
- }
-
- std::vector<T> Pop() {
- const size_t len = Size();
- std::vector<T> result(len);
-
- for (size_t i = 0; i < len; ++i) {
- result[len - i - 1] = PopTop();
- }
-
- return result;
- }
-
- private:
- T PopTop() {
- std::pop_heap(data_.begin(), data_.end(), compare_);
- T result = data_.back();
- data_.pop_back();
- return result;
- }
-
- ContainerType data_;
- CompareFn compare_;
-
- const size_t max_size_;
-};
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_BOTTOM_N_H_
diff --git a/third-party/astc-codec/src/base/math_utils.h b/third-party/astc-codec/src/base/math_utils.h
deleted file mode 100644
index 48f1a24c..00000000
--- a/third-party/astc-codec/src/base/math_utils.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_MATH_UTILS_H_
-#define ASTC_CODEC_BASE_MATH_UTILS_H_
-
-#include "src/base/uint128.h"
-
-#include <cassert>
-#include <cstdint>
-#include <type_traits>
-
-namespace astc_codec {
-namespace base {
-
-inline int Log2Floor(uint32_t n) {
- if (n == 0) {
- return -1;
- }
-
- int log = 0;
- uint32_t value = n;
- for (int i = 4; i >= 0; --i) {
- int shift = (1 << i);
- uint32_t x = value >> shift;
- if (x != 0) {
- value = x;
- log += shift;
- }
- }
- assert(value == 1);
- return log;
-}
-
-inline int CountOnes(uint32_t n) {
- n -= ((n >> 1) & 0x55555555);
- n = ((n >> 2) & 0x33333333) + (n & 0x33333333);
- return static_cast<int>((((n + (n >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);
-}
-
-template<typename T>
-inline T ReverseBits(T value) {
- uint32_t s = sizeof(value) * 8;
- T mask = ~T(0);
- while ((s >>= 1) > 0) {
- mask ^= (mask << s);
- value = ((value >> s) & mask) | ((value << s) & ~mask);
- }
-
- return value;
-}
-
-template<typename T>
-inline T GetBits(T source, uint32_t offset, uint32_t count) {
- static_assert(std::is_same<T, UInt128>::value || std::is_unsigned<T>::value,
- "T must be unsigned.");
-
- const uint32_t total_bits = sizeof(T) * 8;
- assert(count > 0);
- assert(offset + count <= total_bits);
-
- const T mask = count == total_bits ? ~T(0) : ~T(0) >> (total_bits - count);
- return (source >> offset) & mask;
-}
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_MATH_UTILS_H_
diff --git a/third-party/astc-codec/src/base/optional.h b/third-party/astc-codec/src/base/optional.h
deleted file mode 100644
index 5ede4af9..00000000
--- a/third-party/astc-codec/src/base/optional.h
+++ /dev/null
@@ -1,520 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_OPTIONAL_H_
-#define ASTC_CODEC_BASE_OPTIONAL_H_
-
-#include "src/base/type_traits.h"
-
-#include <cassert>
-#include <initializer_list>
-#include <type_traits>
-#include <utility>
-
-#include <cstddef>
-
-// Optional<T> - a template class to store an optional value of type T.
-//
-// Usage examples:
-//
-// Initialization and construction:
-// Optional<Foo> foo; // |foo| doesn't contain a value.
-// Optional<Foo> foo(Foo(10)); // |foo| contains a copy-constructed value.
-// Optional<Foo> foo2(foo); // |foo2| contains a copy of |foo|'s value.
-// Optional<Foo> foo3(std::move(foo2)); // Guess what?
-//
-// Assignment:
-// Foo foo_value(0);
-// Optional<Foo> foo; // |foo| is empty.
-// Optional<Foo> foo2; // |foo2| is empty.
-// foo2 = foo; // |foo2| is still empty.
-// foo = foo_value; // set value of |foo| to a copy of |foo_value|
-// foo = std::move(foo_value); // move |foo_value| into |foo|.
-// foo2 = foo; // now |foo2| has a copy of |foo|'s value.
-// foo = kNullopt; // unset |foo|, it has no value.
-//
-// Checking and accessing value:
-// if (foo) {
-// // |foo| has a value.
-// doStuff(*foo); // |*foo| is the value inside |foo|.
-// foo->callMethod(); // Same as (*foo).callMethod().
-// } else {
-// // |foo| is empty.
-// }
-//
-// foo.value() // Same as *foo
-// foo.valueOr(<default>) // Return <default> is |foo| has no value.
-//
-// In-place construction:
-//
-// Optional<Foo> foo; // |foo| is empty.
-// foo.emplace(20); // |foo| now contains a value constructed as Foo(20)
-//
-// Optional<Foo> foo(kInplace, 20); // |foo| is initialized with a value
-// // that is constructed in-place as
-// // Foo(20).
-//
-// return makeOptional<Foo>(20); // Takes Foo constructor arguments
-// // directly.
-//
-// Returning values:
-//
-// Optional<Foo> myFunc(...) {
-// if (someCondition) {
-// return Foo(10); // call Optional<Foo>(Foo&) constructor.
-// } else {
-// return {}; // call Optional<Foo>() constructor, which
-// // builds an empty value.
-// }
-// }
-//
-// Memory layout:
-// Optional<Foo> is equivalent to:
-//
-// struct {
-// bool flag;
-// Foo value;
-// };
-//
-// in terms of memory layout. This means it *doubles* the size of integral
-// types. Also:
-//
-// - Optional<Foo> can be constructed from anything that constructs a Foo.
-//
-// - Same with Optional<Foo>(kInplace, Args...) where Args... matches any
-// arguments that can be passed to a Foo constructor.
-//
-// - Comparison operators are provided. Beware: an empty Optional<Foo>
-// is always smaller than any Foo value.
-
-namespace astc_codec {
-namespace base {
-
-namespace details {
-
-// Base classes to reduce the number of instantiations of the Optional's
-// internal members.
-class OptionalFlagBase {
- public:
- void setConstructed(bool constructed) { mConstructed = constructed; }
- constexpr bool constructed() const { return mConstructed; }
- constexpr operator bool() const { return constructed(); }
- bool hasValue() const { return constructed(); }
-
- constexpr OptionalFlagBase(bool constructed = false)
- : mConstructed(constructed) { }
-
- private:
- bool mConstructed = false;
-};
-
-template<size_t Size, size_t Align>
-class OptionalStorageBase {
- protected:
- using StoreT = typename std::aligned_storage<Size, Align>::type;
- StoreT mStorage = {};
-};
-
-} // namespace details
-
-// A tag type for empty optional construction
-struct NulloptT {
- constexpr explicit NulloptT(int) { }
-};
-
-// A tag type for inplace value construction
-struct InplaceT {
- constexpr explicit InplaceT(int) { }
-};
-
-// Tag values for null optional and inplace construction
-constexpr NulloptT kNullopt{1};
-constexpr InplaceT kInplace{1};
-
-// Forward declaration for an early use
-template<class T>
-class Optional;
-
-// A type trait for checking if a type is an optional instantiation
-// Note: if you want to refer to the template name inside the template,
-// you need to declare this alias outside of it - because the
-// class name inside of the template stands for an instantiated template
-// E.g, for template <T> class Foo if you say 'Foo' inside the class, it
-// actually means Foo<T>;
-template<class U>
-using is_any_optional =
- is_template_instantiation_of<typename std::decay<U>::type, Optional>;
-
-template<class T>
-class Optional
- : private details::OptionalFlagBase,
- private details::OptionalStorageBase<sizeof(T),
- std::alignment_of<T>::value> {
- // make sure all optionals are buddies - this is needed to implement
- // conversion from optionals of other types
- template<class U>
- friend class Optional;
-
- template<class U>
- using self = Optional<U>;
-
- using base_flag = details::OptionalFlagBase;
- using base_storage =
- details::OptionalStorageBase<sizeof(T), std::alignment_of<T>::value>;
-
- public:
- // std::optional will have this, so let's provide it
- using value_type = T;
-
- // make sure we forbid some Optional instantiations where things may get
- // really messy
- static_assert(!std::is_same<typename std::decay<T>::type, NulloptT>::value,
- "Optional of NulloptT is not allowed");
- static_assert(!std::is_same<typename std::decay<T>::type, InplaceT>::value,
- "Optional of InplaceT is not allowed");
- static_assert(!std::is_reference<T>::value,
- "Optional references are not allowed: use a pointer instead");
-
- // constructors
- constexpr Optional() { }
- constexpr Optional(NulloptT) { }
-
- Optional(const Optional& other) : base_flag(other.constructed()) {
- if (this->constructed()) {
- new (&get()) T(other.get());
- }
- }
- Optional(Optional&& other) : base_flag(other.constructed()) {
- if (this->constructed()) {
- new (&get()) T(std::move(other.get()));
- }
- }
-
- // Conversion constructor from optional of similar type
- template<class U, class = enable_if_c<!is_any_optional<U>::value &&
- std::is_constructible<T, U>::value>>
- Optional(const Optional<U>& other) : base_flag(other.constructed()) {
- if (this->constructed()) {
- new (&get()) T(other.get());
- }
- }
-
- // Move-conversion constructor
- template<class U, class = enable_if_c<!is_any_optional<U>::value &&
- std::is_constructible<T, U>::value>>
- Optional(Optional<U>&& other) : base_flag(other.constructed()) {
- if (this->constructed()) {
- new (&get()) T(std::move(other.get()));
- }
- }
-
- // Construction from a raw value
- Optional(const T& value) : base_flag(true) { new (&get()) T(value); }
- // Move construction from a raw value
- Optional(T&& value) : base_flag(true) { new (&get()) T(std::move(value)); }
-
- // Inplace construction from a list of |T|'s ctor arguments
- template<class... Args>
- Optional(InplaceT, Args&&... args) : base_flag(true) {
- new (&get()) T(std::forward<Args>(args)...);
- }
-
- // Inplace construction from an initializer list passed into |T|'s ctor
- template<class U, class = enable_if<
- std::is_constructible<T, std::initializer_list<U>>>>
- Optional(InplaceT, std::initializer_list<U> il) : base_flag(true) {
- new (&get()) T(il);
- }
-
- // direct assignment
- Optional& operator=(const Optional& other) {
- if (&other == this) {
- return *this;
- }
-
- if (this->constructed()) {
- if (other.constructed()) {
- get() = other.get();
- } else {
- destruct();
- this->setConstructed(false);
- }
- } else {
- if (other.constructed()) {
- new (&get()) T(other.get());
- this->setConstructed(true);
- } else {
- ; // we're good
- }
- }
- return *this;
- }
-
- // move assignment
- Optional& operator=(Optional&& other) {
- if (this->constructed()) {
- if (other.constructed()) {
- get() = std::move(other.get());
- } else {
- destruct();
- this->setConstructed(false);
- }
- } else {
- if (other.constructed()) {
- new (&get()) T(std::move(other.get()));
- this->setConstructed(true);
- } else {
- ; // we're good
- }
- }
- return *this;
- }
-
- // conversion assignment
- template<class U,
- class = enable_if_convertible<typename std::decay<U>::type, T>>
- Optional& operator=(const Optional<U>& other) {
- if (this->constructed()) {
- if (other.constructed()) {
- get() = other.get();
- } else {
- destruct();
- this->setConstructed(false);
- }
- } else {
- if (other.constructed()) {
- new (&get()) T(other.get());
- this->setConstructed(true);
- } else {
- ; // we're good
- }
- }
- return *this;
- }
-
- // conversion move assignment
- template<class U,
- class = enable_if_convertible<typename std::decay<U>::type, T>>
- Optional& operator=(Optional<U>&& other) {
- if (this->constructed()) {
- if (other.constructed()) {
- get() = std::move(other.get());
- } else {
- destruct();
- this->setConstructed(false);
- }
- } else {
- if (other.constructed()) {
- new (&get()) T(std::move(other.get()));
- this->setConstructed(true);
- } else {
- ; // we're good
- }
- }
- return *this;
- }
-
- // the most complicated one: forwarding constructor for anything convertible
- // to |T|, excluding the stuff implemented above explicitly
- template<class U,
- class = enable_if_c<
- !is_any_optional<typename std::decay<U>::type>::value &&
- std::is_convertible<typename std::decay<U>::type, T>::value>>
- Optional& operator=(U&& other) {
- if (this->constructed()) {
- get() = std::forward<U>(other);
- } else {
- new (&get()) T(std::forward<U>(other));
- this->setConstructed(true);
- }
- return *this;
- }
-
- // Adopt value checkers from the parent
- using base_flag::operator bool;
- using base_flag::hasValue;
-
- T& value() {
- assert(this->constructed());
- return get();
- }
- constexpr const T& value() const {
- assert(this->constructed());
- return get();
- }
-
- T* ptr() { return this->constructed() ? &get() : nullptr; }
- constexpr const T* ptr() const {
- return this->constructed() ? &get() : nullptr;
- }
-
- // Value getter with fallback
- template<class U = T,
- class = enable_if_convertible<typename std::decay<U>::type, T>>
- constexpr T valueOr(U&& defaultValue) const {
- return this->constructed() ? get() : std::move(defaultValue);
- }
-
- // Pointer-like operators
- T& operator*() {
- assert(this->constructed());
- return get();
- }
- constexpr const T& operator*() const {
- assert(this->constructed());
- return get();
- }
-
- T* operator->() {
- assert(this->constructed());
- return &get();
- }
- constexpr const T* operator->() const {
- assert(this->constructed());
- return &get();
- }
-
- ~Optional() {
- if (this->constructed()) {
- destruct();
- }
- }
-
- void clear() {
- if (this->constructed()) {
- destruct();
- this->setConstructed(false);
- }
- }
-
- template<class U,
- class = enable_if_convertible<typename std::decay<U>::type, T>>
- void reset(U&& u) {
- *this = std::forward<U>(u);
- }
-
- // In-place construction with possible destruction of the old value
- template<class... Args>
- void emplace(Args&&... args) {
- if (this->constructed()) {
- destruct();
- }
- new (&get()) T(std::forward<Args>(args)...);
- this->setConstructed(true);
- }
-
- // In-place construction with possible destruction of the old value
- // initializer-list version
- template<class U, class = enable_if<
- std::is_constructible<T, std::initializer_list<U>>>>
- void emplace(std::initializer_list<U> il) {
- if (this->constructed()) {
- destruct();
- }
- new (&get()) T(il);
- this->setConstructed(true);
- }
-
- private:
- // A helper function to convert the internal raw storage to T&
- constexpr const T& get() const {
- return *reinterpret_cast<const T*>(
- reinterpret_cast<const char*>(&this->mStorage));
- }
-
- // Same thing, mutable
- T& get() { return const_cast<T&>(const_cast<const Optional*>(this)->get()); }
-
- // Shortcut for a destructor call for the stored object
- void destruct() { get().T::~T(); }
-};
-
-template<class T>
-Optional<typename std::decay<T>::type> makeOptional(T&& t) {
- return Optional<typename std::decay<T>::type>(std::forward<T>(t));
-}
-
-template<class T, class... Args>
-Optional<typename std::decay<T>::type> makeOptional(Args&&... args) {
- return Optional<typename std::decay<T>::type>(kInplace,
- std::forward<Args>(args)...);
-}
-
-template<class T>
-bool operator==(const Optional<T>& l, const Optional<T>& r) {
- return l.hasValue() ? r.hasValue() && *l == *r : !r.hasValue();
-}
-template<class T>
-bool operator==(const Optional<T>& l, NulloptT) {
- return !l;
-}
-template<class T>
-bool operator==(NulloptT, const Optional<T>& r) {
- return !r;
-}
-template<class T>
-bool operator==(const Optional<T>& l, const T& r) {
- return bool(l) && *l == r;
-}
-template<class T>
-bool operator==(const T& l, const Optional<T>& r) {
- return bool(r) && l == *r;
-}
-
-template<class T>
-bool operator!=(const Optional<T>& l, const Optional<T>& r) {
- return !(l == r);
-}
-template<class T>
-bool operator!=(const Optional<T>& l, NulloptT) {
- return bool(l);
-}
-template<class T>
-bool operator!=(NulloptT, const Optional<T>& r) {
- return bool(r);
-}
-template<class T>
-bool operator!=(const Optional<T>& l, const T& r) {
- return !l || !(*l == r);
-}
-template<class T>
-bool operator!=(const T& l, const Optional<T>& r) {
- return !r || !(l == *r);
-}
-
-template<class T>
-bool operator<(const Optional<T>& l, const Optional<T>& r) {
- return !r ? false : (!l ? true : *l < *r);
-}
-template<class T>
-bool operator<(const Optional<T>&, NulloptT) {
- return false;
-}
-template<class T>
-bool operator<(NulloptT, const Optional<T>& r) {
- return bool(r);
-}
-template<class T>
-bool operator<(const Optional<T>& l, const T& r) {
- return !l || *l < r;
-}
-template<class T>
-bool operator<(const T& l, const Optional<T>& r) {
- return bool(r) && l < *r;
-}
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_OPTIONAL_H_
diff --git a/third-party/astc-codec/src/base/string_utils.h b/third-party/astc-codec/src/base/string_utils.h
deleted file mode 100644
index c450b272..00000000
--- a/third-party/astc-codec/src/base/string_utils.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_STRING_UTILS_H_
-#define ASTC_CODEC_BASE_STRING_UTILS_H_
-
-#include <limits>
-#include <string>
-
-namespace astc_codec {
-namespace base {
-
-// Iterates over a string's parts using |splitBy| as a delimiter.
-// |splitBy| must be a nonempty string well, or it's a no-op.
-// Otherwise, |func| is called on each of the splits, excluding the
-// characters that are part of |splitBy|. If two |splitBy|'s occur in a row,
-// |func| will be called on a StringView("") in between. See
-// StringUtils_unittest.cpp for the full story.
-template<class Func>
-void Split(const std::string& str, const std::string& splitBy, Func func) {
- if (splitBy.empty()) {
- return;
- }
-
- size_t splitSize = splitBy.size();
- size_t begin = 0;
- size_t end = str.find(splitBy);
-
- while (true) {
- func(str.substr(begin, end - begin));
- if (end == std::string::npos) {
- return;
- }
-
- begin = end + splitSize;
- end = str.find(splitBy, begin);
- }
-}
-
-static int32_t ParseInt32(const char* str, int32_t deflt) {
- using std::numeric_limits;
-
- char* error = nullptr;
- int64_t value = strtol(str, &error, 0);
- // Limit long values to int32 min/max. Needed for lp64; no-op on 32 bits.
- if (value > std::numeric_limits<int32_t>::max()) {
- value = std::numeric_limits<int32_t>::max();
- } else if (value < std::numeric_limits<int32_t>::min()) {
- value = std::numeric_limits<int32_t>::min();
- }
- return (error == str) ? deflt : static_cast<int32_t>(value);
-}
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_STRING_UTILS_H_
diff --git a/third-party/astc-codec/src/base/test/bit_stream_test.cpp b/third-party/astc-codec/src/base/test/bit_stream_test.cpp
deleted file mode 100644
index 0c4b3c94..00000000
--- a/third-party/astc-codec/src/base/test/bit_stream_test.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/bit_stream.h"
-
-#include <gtest/gtest.h>
-
-namespace astc_codec {
-namespace base {
-
-namespace {
- static constexpr uint64_t kAllBits = 0xFFFFFFFFFFFFFFFF;
- static constexpr uint64_t k40Bits = 0x000000FFFFFFFFFF;
-}
-
-TEST(BitStream, Decode) {
- {
- BitStream<uint64_t> stream(0, 1);
-
- uint64_t bits = kAllBits;
- EXPECT_TRUE(stream.GetBits(1, &bits));
- EXPECT_EQ(bits, 0);
- EXPECT_FALSE(stream.GetBits(1, &bits));
- }
-
- {
- BitStream<uint64_t> stream(0b1010101010101010, 32);
- EXPECT_EQ(stream.Bits(), 32);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(1, &bits));
- EXPECT_EQ(bits, 0);
-
- EXPECT_TRUE(stream.GetBits(3, &bits));
- EXPECT_EQ(bits, 0b101);
-
- EXPECT_TRUE(stream.GetBits(8, &bits));
- EXPECT_EQ(bits, 0b10101010);
-
- EXPECT_EQ(stream.Bits(), 20);
-
- EXPECT_TRUE(stream.GetBits(20, &bits));
- EXPECT_EQ(bits, 0b1010);
- EXPECT_EQ(stream.Bits(), 0);
- }
-
- {
- BitStream<uint64_t> stream(kAllBits, 64);
- EXPECT_EQ(stream.Bits(), 64);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(64, &bits));
- EXPECT_EQ(bits, kAllBits);
- EXPECT_EQ(stream.Bits(), 0);
- }
-
- {
- BitStream<uint64_t> stream(kAllBits, 64);
- EXPECT_EQ(stream.Bits(), 64);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(40, &bits));
- EXPECT_EQ(bits, k40Bits);
- EXPECT_EQ(stream.Bits(), 24);
- }
-
- {
- BitStream<uint64_t> stream(kAllBits, 32);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(0, &bits));
- EXPECT_EQ(bits, 0);
- EXPECT_TRUE(stream.GetBits(32, &bits));
- EXPECT_EQ(bits, k40Bits & 0xFFFFFFFF);
- EXPECT_TRUE(stream.GetBits(0, &bits));
- EXPECT_EQ(bits, 0);
- EXPECT_EQ(stream.Bits(), 0);
- }
-}
-
-TEST(BitStream, Encode) {
- {
- BitStream<uint64_t> stream;
-
- stream.PutBits(0, 1);
- stream.PutBits(0b11, 2);
- EXPECT_EQ(stream.Bits(), 3);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(3, &bits));
- EXPECT_EQ(bits, 0b110);
- }
-
- {
- BitStream<uint64_t> stream;
-
- uint64_t bits = 0;
- stream.PutBits(kAllBits, 64);
- EXPECT_EQ(stream.Bits(), 64);
-
- EXPECT_TRUE(stream.GetBits(64, &bits));
- EXPECT_EQ(bits, kAllBits);
- EXPECT_EQ(stream.Bits(), 0);
- }
-
- {
- BitStream<uint64_t> stream;
- stream.PutBits(kAllBits, 40);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(40, &bits));
- EXPECT_EQ(bits, k40Bits);
- EXPECT_EQ(stream.Bits(), 0);
- }
-
- {
- BitStream<uint64_t> stream;
- stream.PutBits(0, 0);
- stream.PutBits(kAllBits, 32);
- stream.PutBits(0, 0);
-
- uint64_t bits = 0;
- EXPECT_TRUE(stream.GetBits(32, &bits));
- EXPECT_EQ(bits, k40Bits & 0xFFFFFFFF);
- EXPECT_EQ(stream.Bits(), 0);
- }
-}
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/test/bottom_n_test.cpp b/third-party/astc-codec/src/base/test/bottom_n_test.cpp
deleted file mode 100644
index 71265d75..00000000
--- a/third-party/astc-codec/src/base/test/bottom_n_test.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/bottom_n.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace astc_codec {
-namespace base {
-
-using ::testing::ElementsAre;
-
-template<typename T, size_t N>
-static void pushAll(BottomN<T>& heap, const T (&arr)[N]) {
- for (auto i : arr) {
- heap.Push(i);
- }
-}
-
-TEST(BottomN, Sort) {
- {
- BottomN<int> heap(10);
- EXPECT_TRUE(heap.Empty());
- int list[] = { 1,2 };
- pushAll(heap, list);
-
- EXPECT_EQ(heap.Size(), 2);
- EXPECT_FALSE(heap.Empty());
- EXPECT_THAT(heap.Pop(), ElementsAre(1, 2));
- }
-
- {
- BottomN<int> heap(6);
- int list[] = {1, 4, 3, 2, 2, 1};
- pushAll(heap, list);
-
- EXPECT_EQ(heap.Size(), 6);
- EXPECT_THAT(heap.Pop(), ElementsAre(1, 1, 2, 2, 3, 4));
- }
-}
-
-TEST(BottomN, Bounds) {
- {
- BottomN<int> heap(4);
- int list[] = { 1, 2, 3, 4 };
- pushAll(heap, list);
- EXPECT_EQ(heap.Size(), 4);
-
- heap.Push(0);
- EXPECT_EQ(heap.Size(), 4);
-
- EXPECT_THAT(heap.Pop(), ElementsAre(0, 1, 2, 3));
- }
-
- {
- BottomN<int> heap(4);
- int list[] = { 4, 3, 2,1 };
- pushAll(heap, list);
- EXPECT_EQ(heap.Size(), 4);
-
- int list2[] = { 4,4,4,4 };
- pushAll(heap, list2);
- EXPECT_EQ(heap.Size(), 4);
-
- EXPECT_THAT(heap.Pop(), ElementsAre(1, 2, 3, 4));
- }
-
- {
- BottomN<int> heap(4);
- int list[] = { 4, 3, 2, 1 };
- pushAll(heap, list);
- EXPECT_EQ(heap.Size(), 4);
-
- int list2[] = { 5, 5, 5, 5 };
- pushAll(heap, list2);
- EXPECT_EQ(heap.Size(), 4);
-
- EXPECT_THAT(heap.Pop(), ElementsAre(1, 2, 3, 4));
- }
-
- {
- BottomN<int> heap(4);
- int list[] = { 4, 3, 2, 1 };
- pushAll(heap, list);
- EXPECT_EQ(heap.Size(), 4);
-
- int list2[] = { 0, 0, 0, 0 };
- pushAll(heap, list2);
- EXPECT_EQ(heap.Size(), 4);
-
- EXPECT_THAT(heap.Pop(), ElementsAre(0, 0, 0, 0));
- }
-}
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/test/math_utils_test.cpp b/third-party/astc-codec/src/base/test/math_utils_test.cpp
deleted file mode 100644
index 0371e118..00000000
--- a/third-party/astc-codec/src/base/test/math_utils_test.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/math_utils.h"
-
-#include <gtest/gtest.h>
-
-namespace astc_codec {
-namespace base {
-
-TEST(MathUtils, Log2Floor) {
- EXPECT_EQ(-1, Log2Floor(0));
-
- for (int i = 0; i < 32; i++) {
- uint32_t n = 1U << i;
- EXPECT_EQ(i, Log2Floor(n));
- if (n > 2) {
- EXPECT_EQ(i - 1, Log2Floor(n - 1));
- EXPECT_EQ(i, Log2Floor(n + 1));
- }
- }
-}
-
-TEST(MathUtils, CountOnes) {
- EXPECT_EQ(0, CountOnes(0));
- EXPECT_EQ(1, CountOnes(1));
- EXPECT_EQ(32, CountOnes(static_cast<uint32_t>(~0U)));
- EXPECT_EQ(1, CountOnes(0x8000000));
-
- for (int i = 0; i < 32; i++) {
- EXPECT_EQ(1, CountOnes(1U << i));
- EXPECT_EQ(31, CountOnes(static_cast<uint32_t>(~0U) ^ (1U << i)));
- }
-}
-
-TEST(MathUtils, ReverseBits) {
- EXPECT_EQ(ReverseBits(0u), 0u);
- EXPECT_EQ(ReverseBits(1u), 1u << 31);
- EXPECT_EQ(ReverseBits(0xffffffff), 0xffffffff);
- EXPECT_EQ(ReverseBits(0x00000001), 0x80000000);
- EXPECT_EQ(ReverseBits(0x80000000), 0x00000001);
- EXPECT_EQ(ReverseBits(0xaaaaaaaa), 0x55555555);
- EXPECT_EQ(ReverseBits(0x55555555), 0xaaaaaaaa);
- EXPECT_EQ(ReverseBits(0x7d5d7f53), 0xcafebabe);
- EXPECT_EQ(ReverseBits(0xcafebabe), 0x7d5d7f53);
-}
-
-TEST(MathUtils, GetBits) {
- EXPECT_EQ(GetBits(0u, 0, 1), 0u);
- EXPECT_EQ(GetBits(0u, 0, 32), 0u);
- EXPECT_EQ(GetBits(0x00000001u, 0, 1), 0x00000001);
- EXPECT_EQ(GetBits(0x00000001u, 0, 32), 0x00000001);
- EXPECT_EQ(GetBits(0x00000001u, 1, 31), 0x00000000);
- EXPECT_EQ(GetBits(0x00000001u, 31, 1), 0x00000000);
-
- EXPECT_DEBUG_DEATH(GetBits(0x00000000u, 1, 32), "");
- EXPECT_DEBUG_DEATH(GetBits(0x00000000u, 32, 0), "");
- EXPECT_DEBUG_DEATH(GetBits(0x00000000u, 32, 1), "");
-
- EXPECT_EQ(GetBits(0XFFFFFFFFu, 0, 4), 0x0000000F);
- EXPECT_EQ(GetBits(0XFFFFFFFFu, 16, 16), 0xFFFF);
- EXPECT_EQ(GetBits(0x80000000u, 31, 1), 1);
- EXPECT_EQ(GetBits(0xCAFEBABEu, 24, 8), 0xCA);
-}
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/test/optional_test.cpp b/third-party/astc-codec/src/base/test/optional_test.cpp
deleted file mode 100644
index 1eeefbdf..00000000
--- a/third-party/astc-codec/src/base/test/optional_test.cpp
+++ /dev/null
@@ -1,481 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/optional.h"
-
-#include <gtest/gtest.h>
-
-#include <memory>
-#include <vector>
-
-namespace astc_codec {
-namespace base {
-
-TEST(Optional, TypeProperties) {
- // Making sure optional has the correct alignment and doesn't waste too much
- // space
-
- static_assert(sizeof(Optional<bool>) == 2, "bad Optional<bool> size");
- static_assert(std::alignment_of<Optional<bool>>::value ==
- std::alignment_of<bool>::value,
- "bad Optional<bool> alignment");
-
- static_assert(sizeof(Optional<char>) == 2, "bad Optional<char> size");
- static_assert(std::alignment_of<Optional<char>>::value ==
- std::alignment_of<char>::value,
- "bad Optional<char> alignment");
-
- static_assert(sizeof(Optional<int16_t>) == 4, "bad Optional<int16_t> size");
- static_assert(std::alignment_of<Optional<int16_t>>::value ==
- std::alignment_of<int16_t>::value,
- "bad Optional<int16_t> alignment");
-
- static_assert(sizeof(Optional<int32_t>) == 8, "bad Optional<int32_t> size");
- static_assert(std::alignment_of<Optional<int32_t>>::value ==
- std::alignment_of<int32_t>::value,
- "bad Optional<int32_t> alignment");
-
- static_assert(sizeof(Optional<int64_t>) == 16, "bad Optional<int64_t> size");
- static_assert(std::alignment_of<Optional<int64_t>>::value ==
- std::alignment_of<int64_t>::value,
- "bad Optional<int64_t> alignment");
-
- struct S128 {
- int64_t data[2];
- };
-
- static_assert(sizeof(Optional<S128>) == 3 * sizeof(int64_t),
- "bad Optional<S128> size");
- static_assert(std::alignment_of<Optional<S128>>::value ==
- std::alignment_of<S128>::value,
- "bad Optional<S128> alignment");
-}
-
-TEST(Optional, ConstructFromValue) {
- {
- Optional<int> o;
- EXPECT_FALSE(o);
- }
- {
- Optional<int> o = {};
- EXPECT_FALSE(o);
- }
- {
- Optional<int> o = kNullopt;
- EXPECT_FALSE(o);
- }
- {
- Optional<int> o(1);
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
- {
- // check the std::decay<> constructor
- Optional<int> o = static_cast<const short&>(1);
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
- {
- Optional<int> o = 1;
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
- {
- Optional<int> o{1};
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
- {
- short val = 10;
- Optional<int> o = val;
- EXPECT_TRUE(o);
- EXPECT_EQ(10, *o);
- }
- {
- Optional<std::vector<int>> o(kInplace, 10);
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<int>(10)), *o);
- }
- {
- Optional<std::vector<int>> o(kInplace, {1, 2, 3, 4});
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<int>{1, 2, 3, 4}), *o);
- }
-}
-
-TEST(Optional, ConstructFromOptional) {
- {
- Optional<int> o = Optional<int>();
- EXPECT_FALSE(o);
- }
- {
- Optional<short> o2;
- Optional<int> o(o2);
- EXPECT_FALSE(o);
- }
- {
- Optional<short> o2 = 42;
- Optional<int> o(o2);
- EXPECT_TRUE(o);
- EXPECT_EQ(42, *o);
- }
- {
- Optional<int> o(Optional<int>(1));
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
- {
- Optional<int> o2 = 2;
- Optional<int> o = o2;
- EXPECT_TRUE(o);
- EXPECT_EQ(2, *o);
- }
- {
- Optional<std::vector<int>> o2 = std::vector<int>{20, 30, 40};
- Optional<std::vector<int>> o = o2;
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<int>{20, 30, 40}), *o);
- }
-}
-
-TEST(Optional, Assign) {
- {
- Optional<int> o;
- o = 1;
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
-
- o = 2;
- EXPECT_TRUE(o);
- EXPECT_EQ(2, *o);
-
- o = kNullopt;
- EXPECT_FALSE(o);
-
- o = Optional<int>(10);
- EXPECT_TRUE(o);
- EXPECT_EQ(10, *o);
-
- Optional<int> o2;
- o = o2;
- EXPECT_FALSE(o);
-
- o = 2u;
- EXPECT_TRUE(o);
- EXPECT_EQ(2, *o);
-
- o = Optional<short>();
- EXPECT_FALSE(o);
-
- o = Optional<short>(20);
- EXPECT_TRUE(o);
- EXPECT_EQ(20, *o);
-
- Optional<short> o3(200);
- o = o3;
- EXPECT_TRUE(o);
- EXPECT_EQ(200, *o);
-
- o = {};
- EXPECT_FALSE(o);
-
- // check the std::decay<> assignment
- o = static_cast<const short&>(1);
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
-}
-
-TEST(Optional, MakeOptional) {
- {
- auto o = makeOptional(1);
- static_assert(std::is_same<decltype(o), Optional<int>>::value,
- "Bad type deduction in makeOptional()");
- EXPECT_TRUE(o);
- EXPECT_EQ(1, *o);
- }
- {
- auto o = makeOptional(std::vector<char>{'1', '2'});
- static_assert(std::is_same<decltype(o), Optional<std::vector<char>>>::value,
- "Bad type deduction in makeOptional()");
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<char>{'1', '2'}), *o);
- }
- {
- // check std::decay<> in the factory function
- auto o = makeOptional("String");
- static_assert(std::is_same<decltype(o), Optional<const char*>>::value,
- "Bad type deduction in makeOptional()");
- EXPECT_TRUE(o);
- EXPECT_STREQ("String", *o);
- }
- {
- auto o = makeOptional<std::string>("String");
- static_assert(std::is_same<decltype(o), Optional<std::string>>::value,
- "Bad type deduction in makeOptional()");
- EXPECT_TRUE(o);
- EXPECT_STREQ("String", o->c_str());
- }
- {
- auto o = makeOptional<std::string>(5, 'b');
- static_assert(std::is_same<decltype(o), Optional<std::string>>::value,
- "Bad type deduction in makeOptional()");
- EXPECT_TRUE(o);
- EXPECT_STREQ("bbbbb", o->c_str());
- }
- {
- auto o = makeOptional<std::string>();
- static_assert(std::is_same<decltype(o), Optional<std::string>>::value,
- "Bad type deduction in makeOptional()");
- EXPECT_TRUE(o);
- EXPECT_STREQ("", o->c_str());
- }
-}
-
-TEST(Optional, Move) {
- auto o = makeOptional(std::unique_ptr<int>(new int(10)));
- {
- decltype(o) o2 = std::move(o);
- EXPECT_TRUE(o);
- EXPECT_TRUE(o2);
- EXPECT_FALSE(bool(*o));
- EXPECT_TRUE(bool(*o2));
- EXPECT_EQ(10, **o2);
-
- decltype(o) o3;
- o3 = std::move(o2);
- EXPECT_TRUE(o2);
- EXPECT_TRUE(o3);
- EXPECT_FALSE(bool(*o2));
- EXPECT_TRUE(bool(*o3));
- EXPECT_EQ(10, **o3);
-
- o3 = std::move(o2);
- EXPECT_TRUE(o2);
- EXPECT_TRUE(o3);
- EXPECT_FALSE(bool(*o2));
- EXPECT_FALSE(bool(*o3));
- }
-
- {
- decltype(o) o1;
- decltype(o) o2 = std::move(o1);
- EXPECT_FALSE(o1);
- EXPECT_FALSE(o2);
-
- o2 = std::move(o1);
- EXPECT_FALSE(o1);
- EXPECT_FALSE(o2);
-
- decltype(o) o3{kInplace, new int(20)};
- o3 = std::move(o1);
- EXPECT_FALSE(o1);
- EXPECT_FALSE(o3);
- }
-}
-
-TEST(Optional, Value) {
- auto o = makeOptional(1);
- EXPECT_EQ(1, o.value());
- EXPECT_EQ(1, o.valueOr(2));
-
- o = kNullopt;
- EXPECT_EQ(2, o.valueOr(2));
-}
-
-TEST(Optional, Clear) {
- auto o = makeOptional(1);
- o.clear();
- EXPECT_FALSE(o);
-
- o.clear();
- EXPECT_FALSE(o);
-}
-
-TEST(Optional, Emplace) {
- auto o = makeOptional(std::vector<int>{1, 2, 3, 4});
- o.emplace(3, 1);
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<int>{1, 1, 1}), *o);
- EXPECT_EQ(3U, o->capacity());
-
- o.clear();
- o.emplace({1, 2});
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<int>{1, 2}), *o);
- EXPECT_EQ(2U, o->capacity());
-}
-
-TEST(Optional, Reset) {
- auto o = makeOptional(std::vector<int>{1, 2, 3, 4});
- o.reset(std::vector<int>{4, 3});
- EXPECT_TRUE(o);
- EXPECT_EQ((std::vector<int>{4, 3}), *o);
- EXPECT_EQ(2U, o->capacity());
-
- o.clear();
- o.reset(std::vector<int>{1});
- EXPECT_EQ((std::vector<int>{1}), *o);
- EXPECT_EQ(1U, o->capacity());
-}
-
-TEST(Optional, CompareEqual) {
- EXPECT_TRUE(makeOptional(1) == makeOptional(1));
- EXPECT_TRUE(makeOptional(1) == 1);
- EXPECT_TRUE(1 == makeOptional(1));
- EXPECT_FALSE(makeOptional(1) == makeOptional(2));
- EXPECT_FALSE(makeOptional(2) == 1);
- EXPECT_FALSE(2 == makeOptional(1));
- EXPECT_TRUE(makeOptional(1) != makeOptional(2));
- EXPECT_TRUE(makeOptional(1) != 2);
- EXPECT_TRUE(1 != makeOptional(2));
-
- EXPECT_FALSE(makeOptional(1) == kNullopt);
- EXPECT_FALSE(makeOptional(1) == Optional<int>());
- EXPECT_FALSE(kNullopt == makeOptional(1));
- EXPECT_FALSE(Optional<int>() == makeOptional(1));
- EXPECT_TRUE(makeOptional(1) != kNullopt);
- EXPECT_TRUE(makeOptional(1) != Optional<int>());
- EXPECT_TRUE(kNullopt != makeOptional(1));
- EXPECT_TRUE(Optional<int>() != makeOptional(1));
-
- EXPECT_TRUE(kNullopt == Optional<int>());
- EXPECT_TRUE(kNullopt == Optional<char*>());
- EXPECT_FALSE(kNullopt != Optional<int>());
- EXPECT_FALSE(kNullopt != Optional<char*>());
- EXPECT_TRUE(Optional<int>() == Optional<int>());
- EXPECT_FALSE(Optional<int>() != Optional<int>());
-}
-
-TEST(Optional, CompareLess) {
- EXPECT_TRUE(makeOptional(1) < makeOptional(2));
- EXPECT_TRUE(1 < makeOptional(2));
- EXPECT_TRUE(makeOptional(1) < 2);
-
- EXPECT_FALSE(makeOptional(1) < makeOptional(1));
- EXPECT_FALSE(1 < makeOptional(1));
- EXPECT_FALSE(makeOptional(1) < 1);
- EXPECT_FALSE(makeOptional(2) < makeOptional(1));
- EXPECT_FALSE(2 < makeOptional(1));
- EXPECT_FALSE(makeOptional(2) < 1);
-
- EXPECT_TRUE(kNullopt < makeOptional(2));
- EXPECT_TRUE(Optional<int>() < makeOptional(2));
- EXPECT_TRUE(Optional<int>() < 2);
- EXPECT_FALSE(makeOptional(2) < kNullopt);
- EXPECT_FALSE(makeOptional(2) < Optional<int>());
- EXPECT_FALSE(2 < Optional<int>());
-
- EXPECT_FALSE(kNullopt < Optional<int>());
- EXPECT_FALSE(Optional<int>() < kNullopt);
-}
-
-TEST(Optional, Destruction) {
- // create a reference counting class to check if we delete everything
- // we've created
- struct Track {
- Track(int& val) : mVal(val) { ++mVal.get(); }
- Track(std::initializer_list<int*> vals) : mVal(**vals.begin()) {
- ++mVal.get();
- }
- Track(const Track& other) : mVal(other.mVal) { ++mVal.get(); }
- Track(Track&& other) : mVal(other.mVal) { ++mVal.get(); }
- Track& operator=(const Track& other) {
- --mVal.get();
- mVal = other.mVal;
- ++mVal.get();
- return *this;
- }
- Track& operator=(Track&& other) {
- --mVal.get();
- mVal = other.mVal;
- ++mVal.get();
- return *this;
- }
-
- ~Track() { --mVal.get(); }
-
- std::reference_wrapper<int> mVal;
- };
-
- int counter = 0;
- {
- auto o = makeOptional(Track(counter));
- EXPECT_EQ(1, counter);
- }
- EXPECT_EQ(0, counter);
-
- {
- auto o = makeOptional(Track(counter));
- EXPECT_EQ(1, counter);
- o.clear();
- EXPECT_EQ(0, counter);
- }
- EXPECT_EQ(0, counter);
-
- {
- auto o = makeOptional(Track(counter));
- EXPECT_EQ(1, counter);
- int counter2 = 0;
- o.emplace(counter2);
- EXPECT_EQ(0, counter);
- EXPECT_EQ(1, counter2);
- o = Track(counter);
- EXPECT_EQ(1, counter);
- EXPECT_EQ(0, counter2);
-
- auto o2 = o;
- EXPECT_EQ(2, counter);
- EXPECT_EQ(0, counter2);
- }
- EXPECT_EQ(0, counter);
-
- {
- auto o = makeOptional(Track(counter));
- auto o2 = std::move(o);
- EXPECT_EQ(2, counter);
- o = o2;
- EXPECT_EQ(2, counter);
- }
- EXPECT_EQ(0, counter);
-
- int counter2 = 0;
- {
- Optional<Track> o;
- o.emplace(counter);
- EXPECT_EQ(1, counter);
-
- o.emplace(counter2);
- EXPECT_EQ(0, counter);
- EXPECT_EQ(1, counter2);
- }
- EXPECT_EQ(0, counter);
- EXPECT_EQ(0, counter2);
-
- {
- Optional<Track> o;
- o.emplace({&counter});
- EXPECT_EQ(1, counter);
-
- counter2 = 0;
- o.emplace({&counter2});
- EXPECT_EQ(0, counter);
- EXPECT_EQ(1, counter2);
- }
- EXPECT_EQ(0, counter);
- EXPECT_EQ(0, counter2);
-}
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/test/string_utils_test.cpp b/third-party/astc-codec/src/base/test/string_utils_test.cpp
deleted file mode 100644
index 209da54d..00000000
--- a/third-party/astc-codec/src/base/test/string_utils_test.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/string_utils.h"
-
-#include <gtest/gtest.h>
-
-#include <list>
-#include <string>
-#include <vector>
-
-namespace astc_codec {
-namespace base {
-
-TEST(StringUtils, Split) {
- std::vector<std::string> results;
-
- auto testFunc = [&results](std::string&& s) {
- results.push_back(std::move(s));
- };
-
- Split("", "abc", testFunc);
- EXPECT_EQ(results.size(), 1);
-
- Split("abc", "", testFunc);
- EXPECT_EQ(results.size(), 1);
-
- results.clear();
- Split("abc", "a", testFunc);
- EXPECT_EQ(results.size(), 2);
- EXPECT_EQ(results[0], "");
- EXPECT_EQ(results[1], "bc");
-
- results.clear();
- Split("aaa", "a", testFunc);
- EXPECT_EQ(4, results.size());
- EXPECT_EQ("", results[0]);
- EXPECT_EQ("", results[1]);
- EXPECT_EQ("", results[2]);
- EXPECT_EQ("", results[3]);
-
- results.clear();
- Split("1a2a3a4", "a", testFunc);
- EXPECT_EQ(4, results.size());
- EXPECT_EQ("1", results[0]);
- EXPECT_EQ("2", results[1]);
- EXPECT_EQ("3", results[2]);
- EXPECT_EQ("4", results[3]);
-
- results.clear();
- Split("1a2aa3a4", "a", testFunc);
- EXPECT_EQ(5, results.size());
- EXPECT_EQ("1", results[0]);
- EXPECT_EQ("2", results[1]);
- EXPECT_EQ("", results[2]);
- EXPECT_EQ("3", results[3]);
- EXPECT_EQ("4", results[4]);
-
- results.clear();
- Split("The quick brown fox jumped over the lazy dog",
- " ", testFunc);
- EXPECT_EQ(9, results.size());
- EXPECT_EQ("The", results[0]);
- EXPECT_EQ("quick", results[1]);
- EXPECT_EQ("brown", results[2]);
- EXPECT_EQ("fox", results[3]);
- EXPECT_EQ("jumped", results[4]);
- EXPECT_EQ("over", results[5]);
- EXPECT_EQ("the", results[6]);
- EXPECT_EQ("lazy", results[7]);
- EXPECT_EQ("dog", results[8]);
-
- results.clear();
- Split("a; b; c; d", "; ", testFunc);
- EXPECT_EQ(4, results.size());
- EXPECT_EQ("a", results[0]);
- EXPECT_EQ("b", results[1]);
- EXPECT_EQ("c", results[2]);
- EXPECT_EQ("d", results[3]);
-}
-
-TEST(StringUtils, ParseInt32) {
- EXPECT_EQ(ParseInt32("0", -1), 0);
- EXPECT_EQ(ParseInt32("100", -1), 100);
- EXPECT_EQ(ParseInt32("-100", -1), -100);
-
- EXPECT_EQ(ParseInt32("", -1), -1);
- EXPECT_EQ(ParseInt32("a", -1), -1);
- EXPECT_EQ(ParseInt32("10x1", -1), 10);
-
- EXPECT_EQ(ParseInt32("2147483647", -1), 2147483647);
- EXPECT_EQ(ParseInt32("2147483648", -1), 2147483647);
-
- EXPECT_EQ(ParseInt32("-2147483648", -1), -2147483648);
- EXPECT_EQ(ParseInt32("-2147483649", -1), -2147483648);
-}
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/test/type_traits_test.cpp b/third-party/astc-codec/src/base/test/type_traits_test.cpp
deleted file mode 100644
index c724cbe7..00000000
--- a/third-party/astc-codec/src/base/test/type_traits_test.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/type_traits.h"
-
-#include <gtest/gtest.h>
-
-#include <array>
-#include <functional>
-#include <list>
-#include <vector>
-
-namespace astc_codec {
-namespace base {
-
-TEST(TypeTraits, IsCallable) {
- class C;
- C* c = nullptr;
-
- auto lambda = [c](bool) -> C* { return nullptr; };
-
- static_assert(is_callable_as<void(), void()>::value, "simple function");
- static_assert(is_callable_as<void (&)(), void()>::value,
- "function reference");
- static_assert(is_callable_as<void (*)(), void()>::value, "function pointer");
- static_assert(is_callable_as<int(C&, C*), int(C&, C*)>::value,
- "function with arguments and return type");
- static_assert(is_callable_as<decltype(lambda), C*(bool)>::value, "lambda");
- static_assert(is_callable_as<std::function<bool(int)>, bool(int)>::value,
- "std::function");
-
- static_assert(!is_callable_as<int, void()>::value,
- "int should not be callable");
- static_assert(!is_callable_as<C, void()>::value, "incomplete type");
- static_assert(!is_callable_as<void(), void(int)>::value,
- "different arguments");
- static_assert(!is_callable_as<int(), void()>::value,
- "different return types");
- static_assert(!is_callable_as<int(), short()>::value,
- "slightly different return types");
- static_assert(!is_callable_as<int(int), int(int, int)>::value,
- "more arguments");
- static_assert(!is_callable_as<int(int, int), int(int)>::value,
- "less arguments");
-
- static_assert(!is_callable_as<int(int), int>::value,
- "bad required signature");
-
- static_assert(is_callable_with_args<void(), void()>::value,
- "simple function");
- static_assert(is_callable_with_args<void (&)(), void()>::value,
- "function reference");
- static_assert(is_callable_with_args<void (*)(), void()>::value,
- "function pointer");
- static_assert(is_callable_with_args<int(C&, C*), int(C&, C*)>::value,
- "function with arguments and return type");
- static_assert(is_callable_with_args<decltype(lambda), C*(bool)>::value,
- "lambda");
- static_assert(
- is_callable_with_args<std::function<bool(int)>, bool(int)>::value,
- "std::function");
-
- static_assert(!is_callable_with_args<int, void()>::value,
- "int should not be callable");
- static_assert(!is_callable_with_args<C, void()>::value, "incomplete type");
- static_assert(!is_callable_with_args<void(), void(int)>::value,
- "different arguments");
- static_assert(is_callable_with_args<int(), void()>::value,
- "different return types are ignored");
- static_assert(is_callable_with_args<int(), short()>::value,
- "slightly different return types are ignored");
- static_assert(!is_callable_with_args<int(int), int(int, int)>::value,
- "more arguments");
- static_assert(!is_callable_with_args<int(int, int), int(int)>::value,
- "less arguments");
-
- static_assert(!is_callable_with_args<int(int), int>::value,
- "bad required signature");
-}
-
-TEST(TypeTraits, IsTemplateInstantiation) {
- static_assert(!is_template_instantiation_of<int, std::vector>::value,
- "int is not an instance of vector");
- static_assert(!is_template_instantiation_of<std::list<std::vector<int>>,
- std::vector>::value,
- "list is not an instance of vector");
-
- static_assert(
- is_template_instantiation_of<std::vector<int>, std::vector>::value,
- "std::vector<int> is an instance of vector");
- static_assert(
- is_template_instantiation_of<std::vector<std::vector<std::vector<int>>>,
- std::vector>::value,
- "nested std::vector<> is an instance of vector");
-}
-
-#ifndef _MSC_VER
-TEST(TypeTraits, IsRange) {
- static_assert(is_range<std::vector<int>>::value,
- "vector<> should be detected as a range");
- static_assert(is_range<const std::list<std::function<void()>>>::value,
- "const list<> should be detected as a range");
- static_assert(is_range<std::array<std::vector<int>, 10>>::value,
- "array<> should be detected as a range");
- char arr[100];
- static_assert(is_range<decltype(arr)>::value,
- "C array should be detected as a range");
- static_assert(is_range<decltype("string")>::value,
- "String literal should be detected as a range");
-
- static_assert(!is_range<int>::value, "int shouldn't be a range");
- static_assert(!is_range<int*>::value, "int* shouldn't be a range");
- static_assert(!is_range<const int*>::value,
- "even const int* shouldn't be a range");
-}
-#endif
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/test/uint128_test.cpp b/third-party/astc-codec/src/base/test/uint128_test.cpp
deleted file mode 100644
index 0a52244c..00000000
--- a/third-party/astc-codec/src/base/test/uint128_test.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/base/uint128.h"
-
-#include <gtest/gtest.h>
-
-namespace astc_codec {
-namespace base {
-
-TEST(UInt128, Equality) {
- const UInt128 zero(0);
- const UInt128 max64(~0ULL);
-
- EXPECT_EQ(zero, zero);
- EXPECT_NE(zero, max64);
- EXPECT_EQ(zero, UInt128(0));
- EXPECT_NE(zero, UInt128(1));
- EXPECT_EQ(max64, max64);
-}
-
-TEST(UInt128, Shifting) {
- const UInt128 max64(~0ULL);
- const UInt128 upper64(~0ULL, 0);
- EXPECT_EQ(upper64.HighBits(), ~0ULL);
- EXPECT_EQ(upper64.LowBits(), 0);
-
- EXPECT_EQ(upper64 >> 64, max64);
-
- EXPECT_EQ(UInt128(1) << 1, UInt128(2));
- EXPECT_EQ(UInt128(0) << 0, UInt128(0));
- EXPECT_EQ(max64 << 0, max64);
- EXPECT_EQ(max64 >> 0, max64);
- EXPECT_EQ(upper64 << 0, upper64);
- EXPECT_EQ(upper64 >> 0, upper64);
-
- {
- const UInt128 bit63 = UInt128(1ULL << 62) << 1;
- EXPECT_EQ(bit63.LowBits(), 1ULL << 63);
- EXPECT_EQ(bit63.HighBits(), 0);
- }
-
- {
- const UInt128 bit64 = UInt128(1ULL << 63) << 1;
- EXPECT_EQ(bit64.LowBits(), 0);
- EXPECT_EQ(bit64.HighBits(), 1);
- EXPECT_EQ(bit64 >> 1, UInt128(1ULL << 63));
- }
-
- {
- const UInt128 overshift = max64 << 128;
- EXPECT_EQ(overshift.HighBits(), 0);
- EXPECT_EQ(overshift.LowBits(), 0);
- }
-
- {
- const UInt128 overlap = upper64 >> 32;
- EXPECT_EQ(overlap.HighBits(), 0x00000000FFFFFFFF);
- EXPECT_EQ(overlap.LowBits(), 0xFFFFFFFF00000000);
- }
-
- {
- const UInt128 overlap = max64 << 32;
- EXPECT_EQ(overlap.HighBits(), 0x00000000FFFFFFFF);
- EXPECT_EQ(overlap.LowBits(), 0xFFFFFFFF00000000);
- }
-}
-
-TEST(UInt128, LargeShift) {
- const UInt128 base(0xFF);
- EXPECT_EQ(base << 64, UInt128(0xFFULL, 0));
- EXPECT_EQ(base << 72, UInt128(0xFF00ULL, 0));
- EXPECT_EQ(base << 80, UInt128(0xFF0000ULL, 0));
- EXPECT_EQ(base << 88, UInt128(0xFF000000ULL, 0));
- EXPECT_EQ(base << 96, UInt128(0xFF00000000ULL, 0));
- EXPECT_EQ(base << 104, UInt128(0xFF0000000000ULL, 0));
- EXPECT_EQ(base << 112, UInt128(0xFF000000000000ULL, 0));
- EXPECT_EQ(base << 120, UInt128(0xFF00000000000000ULL, 0));
-
- const UInt128 upper(0xFF00000000000000ULL, 0);
- EXPECT_EQ(upper >> 64, UInt128(0, 0xFF00000000000000ULL));
- EXPECT_EQ(upper >> 72, UInt128(0, 0xFF000000000000ULL));
- EXPECT_EQ(upper >> 80, UInt128(0, 0xFF0000000000ULL));
- EXPECT_EQ(upper >> 88, UInt128(0, 0xFF00000000ULL));
- EXPECT_EQ(upper >> 96, UInt128(0, 0xFF000000ULL));
- EXPECT_EQ(upper >> 104, UInt128(0, 0xFF0000ULL));
- EXPECT_EQ(upper >> 112, UInt128(0, 0xFF00ULL));
- EXPECT_EQ(upper >> 120, UInt128(0, 0xFFULL));
-}
-
-TEST(UInt128, BooleanOperators) {
- const UInt128 allOnes(~0ULL, ~0ULL);
- EXPECT_EQ(allOnes.HighBits(), ~0ULL);
- EXPECT_EQ(allOnes.LowBits(), ~0ULL);
-
- EXPECT_EQ(~allOnes, UInt128(0));
- EXPECT_EQ(~UInt128(0), allOnes);
-
- EXPECT_EQ(UInt128(0xFFFF00) & UInt128(0x00FFFF), UInt128(0x00FF00));
- EXPECT_EQ(UInt128(0xFFFF00) | UInt128(0x00FFFF), UInt128(0xFFFFFF));
- EXPECT_EQ(UInt128(0xFFFF00) ^ UInt128(0x00FFFF), UInt128(0xFF00FF));
-}
-
-TEST(UInt128, Addition) {
- const UInt128 bit63(1ULL << 63);
-
- EXPECT_EQ(UInt128(1) + 1, UInt128(2));
- EXPECT_EQ(bit63 + bit63, UInt128(1) << 64);
-
- const UInt128 carryUp = UInt128(~0ULL) + 1;
- EXPECT_EQ(carryUp.HighBits(), 1);
- EXPECT_EQ(carryUp.LowBits(), 0);
-
- const UInt128 allOnes(~0ULL, ~0ULL);
- EXPECT_EQ(allOnes + 1, UInt128(0));
-}
-
-TEST(UInt128, Subtraction) {
- const UInt128 bit64 = UInt128(1) << 64;
- EXPECT_EQ(bit64 - 1, UInt128(~0ULL));
-
- EXPECT_EQ(UInt128(1) - 1, UInt128(0));
-
- const UInt128 allOnes(~0ULL, ~0ULL);
- EXPECT_EQ(UInt128(0) - 1, allOnes);
-}
-
-} // namespace base
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/base/type_traits.h b/third-party/astc-codec/src/base/type_traits.h
deleted file mode 100644
index 917125d2..00000000
--- a/third-party/astc-codec/src/base/type_traits.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_TYPE_TRAITS_H_
-#define ASTC_CODEC_BASE_TYPE_TRAITS_H_
-
-#include <iterator>
-#include <type_traits>
-
-namespace astc_codec {
-namespace base {
-
-namespace details {
-
-// a simple helper class for SFINAE below.
-template<class X = void>
-struct dummy {
- using type = X;
-};
-
-} // namespace details
-
-// add some convenience shortcuts for an overly complex std::enable_if syntax
-
-// Use 'enable_if<Predicate,Type>' instead of
-// 'typename std::enable_if<Predicate::value,Type>::type'
-template<class Predicate, class Type = void*>
-using enable_if = typename std::enable_if<Predicate::value, Type>::type;
-
-// Use 'enable_if_c<BooleanFlag,Type>' instead of
-// 'typename std::enable_if<BooleanFlag,Type>::type'
-template<bool predicate, class Type = void*>
-using enable_if_c = typename std::enable_if<predicate, Type>::type;
-
-// Use 'enable_if_convertible<From,To,Type>' instead of
-// 'typename std::enable_if<std::is_convertible<From,To>::value, Type>::type'
-template<class From, class To, class Type = void*>
-using enable_if_convertible = enable_if<std::is_convertible<From, To>>;
-
-// -----------------------------------------------------------------------------
-// A predicate for checking if some object is callable with a specific
-// signature. Examples:
-//
-// is_callable_as<int, void()>::value == false.
-// is_callable_as<strcmp, void()>::value == false.
-// is_callable_as<strcmp, int(const char*, const char*)>::value == true
-//
-template<class F, class Signature, class X = void>
-struct is_callable_as : std::false_type {};
-
-// This specialization is SFINAE-d out if template arguments can't be combined
-// into a call expression F(), or if the result of that call is not |R|
-template<class F, class R, class... Args>
-struct is_callable_as<F, R(Args...),
- typename std::enable_if<std::is_same<
- typename details::dummy<decltype(std::declval<F>()(
- std::declval<Args>()...))>::type,
- R>::value>::type> : std::true_type {};
-
-//
-// A similar predicate to only check arguments of the function call and ignore
-// the specified return type
-//
-// is_callable_as<strcmp, int(const char*, const char*)>::value == true
-// is_callable_as<strcmp, void(const char*, const char*)>::value == false
-// is_callable_with_args<strcmp, void(const char*, const char*)>::value == true
-//
-template<class F, class Signature, class X = void>
-struct is_callable_with_args : std::false_type {};
-
-template<class F, class R, class... Args>
-struct is_callable_with_args<
- F, R(Args...),
- typename std::enable_if<
- !std::is_same<typename details::dummy<decltype(
- std::declval<F>()(std::declval<Args>()...))>::type,
- F>::value>::type> : std::true_type {};
-
-// -----------------------------------------------------------------------------
-// Check if a type |T| is any instantiation of a template |U|. Examples:
-//
-// is_template_instantiation_of<int, std::vector>::value == false
-// is_template_instantiation_of<
-// std::list<std::vector<int>>, std::vector>::value == false
-// is_template_instantiation_of<std::vector<int>, std::vector>::value == true
-// is_template_instantiation_of<
-// std::vector<std::vector<int>>, std::vector>::value == true
-//
-template<class T, template<class...> class U>
-struct is_template_instantiation_of : std::false_type {};
-
-template<template<class...> class U, class... Args>
-struct is_template_instantiation_of<U<Args...>, U> : std::true_type {};
-// -----------------------------------------------------------------------------
-
-//
-// is_range<T> - check if type |T| is a range-like type.
-//
-// It makes sure that expressions std::begin(t) and std::end(t) are well-formed
-// and those return the same type.
-//
-// Note: with expression SFINAE from C++14 is_range_helper<> could be renamed to
-// is_range<> with no extra code. C++11 needs an extra level of enable_if<>
-// to make it work when the type isn't a range.
-//
-
-namespace details {
-
-template<class T>
-using is_range_helper = std::is_same<
- decltype(std::begin(
- std::declval<typename std::add_lvalue_reference<T>::type>())),
- decltype(
- std::end(std::declval<typename std::add_lvalue_reference<T>::type>()))>;
-
-} // namespace details
-
-template<class T, class = void>
-struct is_range : std::false_type {};
-
-template<class T>
-struct is_range<
- T, typename std::enable_if<details::is_range_helper<T>::value>::type>
- : std::true_type {};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// A class to incapsulate integer sequence 0, 1, ..., <num_args>
-// Seq<int...>
-// Useful to pass function parameters in an array/tuple to call it later.
-//
-
-template<int...>
-struct Seq {};
-
-// A 'maker' class to construct Seq<int...> given only <num_args>
-// value.
-// MakeSeq<N, S...> works this way, e.g.
-//
-// MakeSeq<2> inherits MakeSeq<2 - 1, 2 - 1> == MakeSeq<1, 1>
-// MakeSeq<1, 1> : MakeSeq<1 - 1, 1 - 1, 1> == MakeSeq<0, 0, 1>
-// MakeSeq<0, 0, 1> == MakeSeq<0, S...> and defines |type| = Seq<0, 1>
-
-template<int N, int... S>
-struct MakeSeq : MakeSeq<N - 1, N - 1, S...> {};
-
-template<int... S>
-struct MakeSeq<0, S...> {
- using type = Seq<S...>;
-};
-
-//
-// MakeSeqT alias to quickly create Seq<...>:
-// MakeSeqT<3> == Seq<0, 1, 2>
-template<int... S>
-using MakeSeqT = typename MakeSeq<S...>::type;
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_TYPE_TRAITS_H_
diff --git a/third-party/astc-codec/src/base/uint128.h b/third-party/astc-codec/src/base/uint128.h
deleted file mode 100644
index 481e4eab..00000000
--- a/third-party/astc-codec/src/base/uint128.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_UINT128_H_
-#define ASTC_CODEC_BASE_UINT128_H_
-
-#include <cassert>
-#include <cstdint>
-
-namespace astc_codec {
-namespace base {
-
-class UInt128 {
- public:
- UInt128() = default;
- UInt128(uint64_t low) : low_(low) { }
- UInt128(uint64_t high, uint64_t low) : low_(low), high_(high) { }
- UInt128(const UInt128& other) : low_(other.low_), high_(other.high_) { }
-
- uint64_t LowBits() const { return low_; }
- uint64_t HighBits() const { return high_; }
-
- // Allow explicit casts to uint64_t.
- explicit operator uint64_t() const { return low_; }
-
- // Copy operators.
- UInt128& operator=(const UInt128& other) {
- high_ = other.high_;
- low_ = other.low_;
- return *this;
- }
-
- // Equality operators.
- bool operator==(const UInt128& other) const {
- return high_ == other.high_ && low_ == other.low_;
- }
-
- bool operator!=(const UInt128& other) const {
- return high_ != other.high_ || low_ != other.low_;
- }
-
- // Shifting.
- UInt128& operator<<=(int shift) {
- high_ = shift >= 64 ? (shift >= 128 ? 0 : low_ << (shift - 64))
- : high_ << shift;
-
- if (shift > 0 && shift < 64) {
- const uint64_t overlappingBits = low_ >> (64 - shift);
- high_ |= overlappingBits;
- }
-
- low_ = shift >= 64 ? 0 : low_ << shift;
- return *this;
- }
-
- UInt128 operator<<(int shift) const {
- UInt128 result = *this;
- result <<= shift;
- return result;
- }
-
- UInt128& operator>>=(int shift) {
- low_ = shift >= 64 ? (shift >= 128 ? 0 : high_ >> (shift - 64))
- : low_ >> shift;
-
- if (shift > 0 && shift < 64) {
- const uint64_t overlappingBits = high_ << (64 - shift);
- low_ |= overlappingBits;
- }
-
- high_ = shift >= 64 ? 0 : high_ >> shift;
-
- return *this;
- }
-
- UInt128 operator>>(int shift) const {
- UInt128 result = *this;
- result >>= shift;
- return result;
- }
-
- // Binary operations.
- UInt128& operator|=(const UInt128& other) {
- high_ |= other.high_;
- low_ |= other.low_;
- return *this;
- }
-
- UInt128 operator|(const UInt128& other) const {
- UInt128 result = *this;
- result |= other;
- return result;
- }
-
- UInt128& operator&=(const UInt128& other) {
- high_ &= other.high_;
- low_ &= other.low_;
- return *this;
- }
-
- UInt128 operator&(const UInt128& other) const {
- UInt128 result = *this;
- result &= other;
- return result;
- }
-
- UInt128& operator^=(const UInt128& other) {
- high_ ^= other.high_;
- low_ ^= other.low_;
- return *this;
- }
-
- UInt128 operator^(const UInt128& other) const {
- UInt128 result = *this;
- result ^= other;
- return result;
- }
-
- UInt128 operator~() const {
- UInt128 result = *this;
- result.high_ = ~high_;
- result.low_ = ~low_;
- return result;
- }
-
- // Addition/subtraction.
- UInt128& operator+=(const UInt128& other) {
- const uint64_t carry =
- (((low_ & other.low_) & 1) + (low_ >> 1) + (other.low_ >> 1)) >> 63;
- high_ += other.high_ + carry;
- low_ += other.low_;
- return *this;
- }
-
- UInt128 operator+(const UInt128& other) const {
- UInt128 result = *this;
- result += other;
- return result;
- }
-
- UInt128& operator-=(const UInt128& other) {
- low_ -= other.low_;
- const uint64_t carry =
- (((low_ & other.low_) & 1) + (low_ >> 1) + (other.low_ >> 1)) >> 63;
- high_ -= other.high_ + carry;
- return *this;
- }
-
- UInt128 operator-(const UInt128& other) const {
- UInt128 result = *this;
- result -= other;
- return result;
- }
-
- private:
- // TODO(google): Different order for little endian.
- uint64_t low_ = 0;
- uint64_t high_ = 0;
-};
-
-} // namespace base
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_BASE_UINT128_H_
diff --git a/third-party/astc-codec/src/base/utils.h b/third-party/astc-codec/src/base/utils.h
deleted file mode 100644
index 0a4fabdc..00000000
--- a/third-party/astc-codec/src/base/utils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_BASE_UTILS_H_
-#define ASTC_CODEC_BASE_UTILS_H_
-
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-
-#ifdef NDEBUG
-#define UTILS_RELEASE_ASSERT(x) \
- do { \
- const bool result = (x); \
- if (!result) { \
- fprintf(stderr, "Error: UTILS_RELEASE_ASSERT failed: %s\n", #x); \
- abort(); \
- } \
- } while (false)
-#else
-#define UTILS_RELEASE_ASSERT(x) assert(x)
-#endif
-
-#endif // ASTC_CODEC_BASE_UTILS_H_
diff --git a/third-party/astc-codec/src/decoder/Android.bp b/third-party/astc-codec/src/decoder/Android.bp
deleted file mode 100644
index fb5d5c0b..00000000
--- a/third-party/astc-codec/src/decoder/Android.bp
+++ /dev/null
@@ -1,29 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "device_generic_vulkan-cereal_third-party_astc-codec_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "device_generic_vulkan-cereal_third-party_astc-codec_license",
- ],
-}
-
-cc_library_static {
- name: "gfxstream_astc_codec",
- defaults: [ "gfxstream_defaults" ],
- header_libs: [ "gfxstream_astc_codec_headers" ],
- srcs: [
- "footprint.cc",
- "astc_file.cc",
- "endpoint_codec.cc",
- "integer_sequence_codec.cc",
- "intermediate_astc_block.cc",
- "logical_astc_block.cc",
- "partition.cc",
- "physical_astc_block.cc",
- "quantization.cc",
- "weight_infill.cc",
- "codec.cc",
- ],
-}
diff --git a/third-party/astc-codec/src/decoder/BUILD.bazel b/third-party/astc-codec/src/decoder/BUILD.bazel
deleted file mode 100644
index f2fded5e..00000000
--- a/third-party/astc-codec/src/decoder/BUILD.bazel
+++ /dev/null
@@ -1,238 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-cc_library(
- name = "footprint",
- srcs = ["footprint.cc"],
- hdrs = ["footprint.h"],
- deps = [
- "//:api",
- "//src/base",
- ],
-)
-
-cc_library(
- name = "astc_utils",
- srcs = [
- "astc_file.cc",
- "endpoint_codec.cc",
- "integer_sequence_codec.cc",
- "intermediate_astc_block.cc",
- "logical_astc_block.cc",
- "partition.cc",
- "physical_astc_block.cc",
- "quantization.cc",
- "weight_infill.cc",
- ],
- hdrs = [
- "astc_file.h",
- "endpoint_codec.h",
- "integer_sequence_codec.h",
- "intermediate_astc_block.h",
- "logical_astc_block.h",
- "partition.h",
- "physical_astc_block.h",
- "quantization.h",
- "types.h",
- "weight_infill.h",
- ],
- deps = [
- ":footprint",
- "//src/base",
- ],
-)
-
-cc_library(
- name = "codec",
- srcs = ["codec.cc"],
- hdrs = ["codec.h"],
- deps = [
- ":astc_utils",
- ":footprint",
- "//src/base",
- ],
- visibility = ["//:__pkg__"],
-)
-
-cc_binary(
- name = "astc_inspector_cli",
- srcs = ["tools/astc_inspector_cli.cc"],
- deps = [
- ":astc_utils",
- "//src/base",
- ],
-)
-
-################################################################################
-##
-## Testing
-##
-################################################################################
-
-cc_library(
- name = "test",
- hdrs = ["test/image_utils.h"],
- deps = [
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "physical_astc_block_test",
- size = "small",
- srcs = ["test/physical_astc_block_test.cc"],
- deps = [
- ":astc_utils",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "partition_test",
- size = "small",
- srcs = ["test/partition_test.cc"],
- deps = [
- ":astc_utils",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "integer_sequence_codec_test",
- size = "small",
- srcs = ["test/integer_sequence_codec_test.cc"],
- deps = [
- ":astc_utils",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "intermediate_astc_block_test",
- size = "small",
- srcs = ["test/intermediate_astc_block_test.cc"],
- data = glob([
- "testdata/checkered_*.astc",
- ]),
- deps = [
- ":astc_utils",
- ":test",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "quantization_test",
- size = "medium",
- srcs = ["test/quantization_test.cc"],
- deps = [
- ":astc_utils",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "weight_infill_test",
- size = "small",
- srcs = ["test/weight_infill_test.cc"],
- deps = [
- ":astc_utils",
- ":footprint",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "endpoint_codec_test",
- size = "small",
- srcs = ["test/endpoint_codec_test.cc"],
- data = [
- ":testdata/checkerboard.astc",
- ],
- deps = [
- ":astc_utils",
- ":test",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "logical_astc_block_test",
- size = "large",
- srcs = ["test/logical_astc_block_test.cc"],
- data = glob([
- "testdata/atlas_small_*.astc",
- "testdata/atlas_small_*.bmp",
- "testdata/footprint_*.astc",
- "testdata/footprint_*.bmp",
- "testdata/rgb_*.astc",
- "testdata/rgb_*.bmp",
- ]),
- deps = [
- ":test",
- ":astc_utils",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "codec_test",
- size = "large",
- srcs = ["test/codec_test.cc"],
- data = glob([
- "testdata/atlas_small_*.astc",
- "testdata/atlas_small_*.bmp",
- ]),
- deps = [
- ":test",
- ":codec",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "footprint_test",
- size = "small",
- srcs = ["test/footprint_test.cc"],
- deps = [
- ":footprint",
- "@gtest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "astc_fuzzer",
- srcs = ["test/astc_fuzzer.cc"],
- copts = select({
- # Clang-only flags. TODO: Find a better way to detect GCC/clang.
- "@bazel_tools//src/conditions:darwin_x86_64": [
- "-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp",
- "-fsanitize-coverage=bb",
- ],
- "@bazel_tools//src/conditions:darwin": [
- "-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp",
- "-fsanitize-coverage=bb",
- ],
- # GCC-only flags.
- "//conditions:default": [
- "-finstrument-functions"
- ],
- }),
- deps = [
- ":codec",
- "@honggfuzz//:honggfuzz",
- "@benchmark//:benchmark",
- ],
- linkstatic = 1,
-)
diff --git a/third-party/astc-codec/src/decoder/CMakeLists.txt b/third-party/astc-codec/src/decoder/CMakeLists.txt
deleted file mode 100644
index e82a692c..00000000
--- a/third-party/astc-codec/src/decoder/CMakeLists.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2018 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
-# use this file except in compliance with the License. You may obtain a copy of
-# the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations under
-# the License.
-add_library(footprint footprint.cc)
-target_link_libraries(footprint base)
-
-add_library(astc_utils
- astc_file.cc
- endpoint_codec.cc
- integer_sequence_codec.cc
- intermediate_astc_block.cc
- logical_astc_block.cc
- partition.cc
- physical_astc_block.cc
- quantization.cc
- weight_infill.cc)
-target_link_libraries(astc_utils PRIVATE base footprint)
-target_include_directories(astc_utils PRIVATE ../..)
-
-add_library(astc-codec codec.cc)
-target_link_libraries(astc-codec PRIVATE astc_utils)
-target_include_directories(astc-codec PUBLIC ../../include)
-target_include_directories(astc-codec PRIVATE ../..)
-
-add_executable(astc_inspector_cli tools/astc_inspector_cli.cc)
-target_include_directories(astc_inspector_cli PRIVATE ../..)
-target_link_libraries(astc_inspector_cli PRIVATE astc_utils)
-
-#
-# Testing
-#
-if(OPTION_ASTC_TESTS)
- # Note that we will execute all the tests in the project directory.
- # We do this to ensure the unit tests can pick up the required test data
-
- # Create interface library exposing the root as an include directory
- add_library(codec_test_dependencies INTERFACE)
- target_include_directories(codec_test_dependencies INTERFACE ../..)
-
- add_executable(physical_astc_block_test test/physical_astc_block_test.cc)
- add_test(NAME physical_astc_block_test COMMAND physical_astc_block_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(physical_astc_block_test astc_utils codec_test_dependencies gmock_main)
-
- add_executable(partition_test test/partition_test.cc)
- add_test(NAME partition_test COMMAND partition_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(partition_test PRIVATE astc_utils codec_test_dependencies gmock_main)
-
- add_executable(integer_sequence_codec_test test/integer_sequence_codec_test.cc)
- target_link_libraries(integer_sequence_codec_test PRIVATE astc_utils codec_test_dependencies gmock_main)
-
- add_executable(intermediate_astc_block_test test/intermediate_astc_block_test.cc)
- add_test(NAME intermediate_astc_block_test COMMAND intermediate_astc_block_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(intermediate_astc_block_test PRIVATE astc_utils codec_test_dependencies gmock_main)
-
- add_executable(quantization_test test/quantization_test.cc)
- add_test(NAME quantization_test COMMAND quantization_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(quantization_test PRIVATE astc_utils codec_test_dependencies gmock_main)
-
- add_executable(weight_infill_test test/weight_infill_test.cc)
- add_test(NAME weight_infill_test COMMAND weight_infill_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(weight_infill_test PRIVATE astc_utils footprint codec_test_dependencies gmock_main)
-
- add_executable(endpoint_codec_test test/endpoint_codec_test.cc)
- add_test(NAME endpoint_codec_test COMMAND endpoint_codec_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(endpoint_codec_test PRIVATE astc_utils codec_test_dependencies gmock_main)
-
- add_executable(logical_astc_block_test test/logical_astc_block_test.cc)
- add_test(NAME logical_astc_block_test COMMAND logical_astc_block_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(logical_astc_block_test PRIVATE astc_utils codec_test_dependencies gmock_main)
-
- add_executable(codec_test test/codec_test.cc)
- add_test(NAME codec_test COMMAND codec_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
-
- target_link_libraries(codec_test PRIVATE astc-codec codec_test_dependencies gmock_main)
-
- add_executable(footprint_test test/footprint_test.cc)
- add_test(NAME footprint_test COMMAND footprint_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
- target_link_libraries(footprint_test PRIVATE footprint codec_test_dependencies gmock_main)
-
- if(OPTION_BUILD_FUZZER)
- message(FATAL_ERROR "Not yet supported due to missing dependencies")
- add_executable(astc_fuzzer test/astc_fuzzer.cc codec_test_dependencies gmock_main)
- target_link_libraries(astc_fuzzer PRIVATE astc-codec honggfuzz benchmark)
- endif()
-endif()
diff --git a/third-party/astc-codec/src/decoder/astc_file.cc b/third-party/astc-codec/src/decoder/astc_file.cc
deleted file mode 100644
index 47700648..00000000
--- a/third-party/astc-codec/src/decoder/astc_file.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/astc_file.h"
-
-#include <cstring>
-#include <fstream>
-#include <memory>
-#include <sstream>
-
-namespace astc_codec {
-
-namespace {
-static constexpr size_t kASTCHeaderSize = 16;
-
-// Reads a value of size T from the buffer at the current offset, then
-// increments the offset.
-template<typename T>
-inline T ReadVal(const char* file_data, size_t& offset) {
- T x;
- memcpy(&x, &file_data[offset], sizeof(T));
- offset += sizeof(T);
- return x;
-}
-} // namespace
-
-ASTCFile::ASTCFile(Header&& header, std::string&& blocks)
- : header_(std::move(header)), blocks_(std::move(blocks)) {}
-
-std::unique_ptr<ASTCFile> ASTCFile::LoadFromMemory(const char* data,
- size_t length,
- std::string* error) {
- if (length < kASTCHeaderSize) {
- *error = "Incomplete header.";
- return nullptr;
- }
-
- base::Optional<Header> header_opt = ParseHeader(data);
- if (!header_opt) {
- *error = "Invalid ASTC header.";
- return nullptr;
- }
-
- Header header = header_opt.value();
-
- if (header.block_width_ == 0 || header.block_height_ == 0) {
- *error = "Invalid block size.";
- return nullptr;
- }
-
- std::string blocks(data + kASTCHeaderSize, data + length);
-
- // Check that this file has the expected number of blocks.
- const size_t expected_block_count =
- ((header.width_ + header.block_width_ - 1) / header.block_width_) *
- ((header.height_ + header.block_height_ - 1) / header.block_height_);
-
- if (blocks.size() % PhysicalASTCBlock::kSizeInBytes != 0 ||
- blocks.size() / PhysicalASTCBlock::kSizeInBytes != expected_block_count) {
- std::stringstream ss;
- ss << "Unexpected file length " << blocks.size() << " expected "
- << kASTCHeaderSize +
- expected_block_count * PhysicalASTCBlock::kSizeInBytes
- << " bytes.";
- *error = ss.str();
- return nullptr;
- }
-
- return std::unique_ptr<ASTCFile>(
- new ASTCFile(std::move(header), std::move(blocks)));
-}
-
-std::unique_ptr<ASTCFile> ASTCFile::LoadFile(const std::string& path,
- std::string* error) {
- std::ifstream is(path, std::ios::binary);
- if (!is) {
- *error = "File not found: " + path;
- return nullptr;
- }
-
- char header_data[kASTCHeaderSize] = {};
- if (!is.read(header_data, kASTCHeaderSize)) {
- *error = "Failed to load ASTC header.";
- return nullptr;
- }
-
- base::Optional<Header> header_opt = ParseHeader(header_data);
- if (!header_opt) {
- *error = "Invalid ASTC header.";
- return nullptr;
- }
-
- Header header = header_opt.value();
-
- std::string blocks;
- {
- std::ostringstream ss;
- ss << is.rdbuf();
- blocks = ss.str();
- }
-
- // Check that this file has the expected number of blocks.
- const size_t expected_block_count =
- ((header.width_ + header.block_width_ - 1) / header.block_width_) *
- ((header.height_ + header.block_height_ - 1) / header.block_height_);
-
- if (blocks.size() % PhysicalASTCBlock::kSizeInBytes != 0 ||
- blocks.size() / PhysicalASTCBlock::kSizeInBytes != expected_block_count) {
- std::stringstream ss;
- ss << "Unexpected file length " << blocks.size() << " expected "
- << kASTCHeaderSize +
- expected_block_count * PhysicalASTCBlock::kSizeInBytes
- << " bytes.";
- *error = ss.str();
- return nullptr;
- }
-
- return std::unique_ptr<ASTCFile>(
- new ASTCFile(std::move(header), std::move(blocks)));
-}
-
-base::Optional<Footprint> ASTCFile::GetFootprint() const {
- return Footprint::FromDimensions(header_.block_width_, header_.block_height_);
-}
-
-std::string ASTCFile::GetFootprintString() const {
- std::stringstream footprint;
- footprint << header_.block_width_ << "x" << header_.block_height_;
- return footprint.str();
-}
-
-const std::string& ASTCFile::GetRawBlockData() const {
- return blocks_;
-}
-
-PhysicalASTCBlock ASTCFile::GetBlock(size_t block_idx) const {
- const size_t sz = PhysicalASTCBlock::kSizeInBytes;
- const size_t offset = PhysicalASTCBlock::kSizeInBytes * block_idx;
- assert(offset <= blocks_.size() - sz);
- return PhysicalASTCBlock(blocks_.substr(offset, sz));
-}
-
-base::Optional<ASTCFile::Header> ASTCFile::ParseHeader(const char* header) {
- size_t offset = 0;
- // TODO(google): Handle endianness.
- const uint32_t magic = ReadVal<uint32_t>(header, offset);
- if (magic != 0x5CA1AB13) {
- return {};
- }
-
- const uint32_t block_width = ReadVal<uint8_t>(header, offset);
- const uint32_t block_height = ReadVal<uint8_t>(header, offset);
- const uint32_t block_depth = ReadVal<uint8_t>(header, offset);
-
- uint32_t width = 0;
- width |= ReadVal<uint8_t>(header, offset);
- width |= ReadVal<uint8_t>(header, offset) << 8;
- width |= ReadVal<uint8_t>(header, offset) << 16;
-
- uint32_t height = 0;
- height |= ReadVal<uint8_t>(header, offset);
- height |= ReadVal<uint8_t>(header, offset) << 8;
- height |= ReadVal<uint8_t>(header, offset) << 16;
-
- uint32_t depth = 0;
- depth |= ReadVal<uint8_t>(header, offset);
- depth |= ReadVal<uint8_t>(header, offset) << 8;
- depth |= ReadVal<uint8_t>(header, offset) << 16;
- assert(offset == kASTCHeaderSize);
-
- return Header(width, height, depth, block_width, block_height, block_depth);
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/astc_file.h b/third-party/astc-codec/src/decoder/astc_file.h
deleted file mode 100644
index c31c2ba7..00000000
--- a/third-party/astc-codec/src/decoder/astc_file.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_ASTC_FILE_H_
-#define ASTC_CODEC_DECODER_ASTC_FILE_H_
-
-#include "src/base/optional.h"
-#include "src/decoder/footprint.h"
-#include "src/decoder/physical_astc_block.h"
-
-#include <memory>
-#include <string>
-
-namespace astc_codec {
-
-// A thin wrapper around a .astc file on disk. This class simply reads the ASTC
-// header, and stores the block data in memory.
-class ASTCFile {
- private:
- struct Header {
- Header(size_t width, size_t height, size_t depth, size_t block_width,
- size_t block_height, size_t block_depth)
- : width_(width),
- height_(height),
- depth_(depth),
- block_width_(block_width),
- block_height_(block_height),
- block_depth_(block_depth) {}
-
- size_t width_;
- size_t height_;
- size_t depth_;
-
- size_t block_width_;
- size_t block_height_;
- size_t block_depth_;
- };
-
- ASTCFile(ASTCFile::Header&& header, std::string&& blocks);
-
- public:
- // Load an ASTC file from memory.
- // If loading failed, nullptr is returned and an error string is populated
- // in the error parameter.
- static std::unique_ptr<ASTCFile> LoadFromMemory(const char* data,
- size_t length,
- std::string* error);
-
- // Load an ASTC file from file.
- // If loading failed, nullptr is returned and an error string is populated
- // in the error parameter.
- static std::unique_ptr<ASTCFile> LoadFile(const std::string& path,
- std::string* error);
-
- // Returns the footprint for the file, if it is considered to be a valid
- // footprint.
- base::Optional<Footprint> GetFootprint() const;
-
- // Returns the string of the form "NxM" where N and M are the width and height
- // of the block footprint, respectively.
- std::string GetFootprintString() const;
-
- // Get the raw block data for the astc file.
- const std::string& GetRawBlockData() const;
-
- // Returns the physical block at the associated block index.
- PhysicalASTCBlock GetBlock(size_t block_idx) const;
-
- size_t GetWidth() const { return header_.width_; }
- size_t GetHeight() const { return header_.height_; }
- size_t GetDepth() const { return header_.depth_; }
-
- size_t NumBlocks() const {
- return blocks_.size() / PhysicalASTCBlock::kSizeInBytes;
- }
-
- private:
- static base::Optional<ASTCFile::Header> ParseHeader(const char* header);
-
- const Header header_;
- const std::string blocks_;
-};
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_ASTC_FILE_H_
diff --git a/third-party/astc-codec/src/decoder/codec.cc b/third-party/astc-codec/src/decoder/codec.cc
deleted file mode 100644
index c0f8c07b..00000000
--- a/third-party/astc-codec/src/decoder/codec.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/codec.h"
-#include "src/base/uint128.h"
-#include "src/decoder/logical_astc_block.h"
-#include "src/decoder/physical_astc_block.h"
-
-#include <cstring>
-
-namespace astc_codec {
-
-namespace {
-static constexpr size_t kBytesPerPixelUNORM8 = 4;
-}
-
-bool DecompressToImage(const uint8_t* astc_data, size_t astc_data_size,
- size_t width, size_t height, Footprint footprint,
- uint8_t* out_buffer, size_t out_buffer_size,
- size_t out_buffer_stride) {
- const size_t block_width = footprint.Width();
- const size_t block_height = footprint.Height();
- assert(block_width != 0);
- assert(block_height != 0);
-
- if (width == 0 || height == 0) {
- return false;
- }
-
- const size_t blocks_wide = (width + block_width - 1) / block_width;
- assert(blocks_wide != 0);
-
- // Check that this buffer has the expected number of blocks.
- const size_t expected_block_count =
- ((width + block_width - 1) / block_width) *
- ((height + block_height - 1) / block_height);
-
- if (astc_data_size % PhysicalASTCBlock::kSizeInBytes != 0 ||
- astc_data_size / PhysicalASTCBlock::kSizeInBytes !=
- expected_block_count) {
- // TODO(google): Expose error?
- return false;
- }
-
- if (kBytesPerPixelUNORM8 * width > out_buffer_stride ||
- out_buffer_stride * height < out_buffer_size) {
- // Output buffer too small.
- return false;
- }
-
- base::UInt128 block;
- static_assert(sizeof(block) == PhysicalASTCBlock::kSizeInBytes,
- "Block size mismatch");
-
- for (size_t i = 0; i < astc_data_size; i += PhysicalASTCBlock::kSizeInBytes) {
- const size_t block_index = i / PhysicalASTCBlock::kSizeInBytes;
- const size_t block_x = block_index % blocks_wide;
- const size_t block_y = block_index / blocks_wide;
- memcpy(&block, astc_data + i, sizeof(block));
-
- PhysicalASTCBlock physical_block(block);
- auto lb = UnpackLogicalBlock(footprint, physical_block);
- if (!lb) {
- return false;
- }
-
- LogicalASTCBlock logical_block = lb.value();
-
- for (size_t y = 0; y < block_height; ++y) {
- const size_t py = block_height * block_y + y;
- uint8_t* out_row = out_buffer + py * out_buffer_stride;
-
- for (size_t x = 0; x < block_width; ++x) {
- const size_t px = block_width * block_x + x;
-
- // Skip out of bounds.
- if (px >= width || py >= height) {
- continue;
- }
-
- uint8_t* pixel = out_row + px * kBytesPerPixelUNORM8;
- const RgbaColor decoded_color = logical_block.ColorAt(x, y);
- for (size_t i = 0; i < kBytesPerPixelUNORM8; ++i) {
- pixel[i] = static_cast<uint8_t>(decoded_color[i]);
- }
- }
- }
- }
-
- return true;
-}
-
-bool DecompressToImage(const ASTCFile& file, uint8_t* out_buffer,
- size_t out_buffer_size, size_t out_buffer_stride) {
- base::Optional<Footprint> footprint = file.GetFootprint();
- if (!footprint) {
- return false;
- }
-
- return DecompressToImage(
- reinterpret_cast<const uint8_t*>(file.GetRawBlockData().c_str()),
- file.GetRawBlockData().size(), file.GetWidth(), file.GetHeight(),
- footprint.value(), out_buffer, out_buffer_size, out_buffer_stride);
-}
-
-bool ASTCDecompressToRGBA(const uint8_t* astc_data, size_t astc_data_size,
- size_t width, size_t height, FootprintType footprint,
- uint8_t* out_buffer, size_t out_buffer_size,
- size_t out_buffer_stride) {
- base::Optional<Footprint> footprint_opt =
- Footprint::FromFootprintType(footprint);
- if (!footprint_opt) {
- return false;
- }
-
- return DecompressToImage(astc_data, astc_data_size, width, height,
- footprint_opt.value(), out_buffer, out_buffer_size,
- out_buffer_stride);
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/codec.h b/third-party/astc-codec/src/decoder/codec.h
deleted file mode 100644
index eed601a4..00000000
--- a/third-party/astc-codec/src/decoder/codec.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_CODEC_H_
-#define ASTC_CODEC_DECODER_CODEC_H_
-
-#include "src/decoder/astc_file.h"
-#include "src/decoder/footprint.h"
-
-#include <string>
-
-namespace astc_codec {
-
-// Decompresses ASTC blocks to an image buffer.
-// Returns true if the decompression succeeded and the out buffer has been
-// filled.
-bool DecompressToImage(const uint8_t* astc_data, size_t astc_data_size,
- size_t width, size_t height, Footprint footprint,
- uint8_t* out_buffer, size_t out_buffer_size,
- size_t out_buffer_stride);
-
-// Decompresses an ASTC file to an image buffer.
-// Returns true if the decompression succeeded and the out buffer has been
-// filled.
-bool DecompressToImage(const ASTCFile& file, uint8_t* out_buffer,
- size_t out_buffer_size, size_t out_buffer_stride);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_CODEC_H_
diff --git a/third-party/astc-codec/src/decoder/endpoint_codec.cc b/third-party/astc-codec/src/decoder/endpoint_codec.cc
deleted file mode 100644
index 1513d15a..00000000
--- a/third-party/astc-codec/src/decoder/endpoint_codec.cc
+++ /dev/null
@@ -1,967 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/endpoint_codec.h"
-#include "src/decoder/quantization.h"
-
-#include <algorithm>
-#include <array>
-#include <numeric>
-#include <utility>
-
-namespace astc_codec {
-
-namespace {
-
-template<typename T>
-T Clamp(T value, T min, T max) {
- return value < min ? min : (value > max ? max : value);
-}
-
-// This is the 'blue_contract' function defined in Section C.2.14 of the ASTC
-// specification.
-template<typename ArrayType>
-void BlueContract(ArrayType* const cptr) {
- ArrayType& c = *cptr;
- c[0] = (c[0] + c[2]) >> 1;
- c[1] = (c[1] + c[2]) >> 1;
-}
-
-// Returns the inverse of values in BlueContract, subjected to the constraint
-// that the new values are stored in the range [0, 255].
-template<typename ArrayType>
-ArrayType InvertBlueContract(const ArrayType& c) {
- ArrayType result = c;
- result[0] = Clamp(2 * c[0] - c[2], 0, 255);
- result[1] = Clamp(2 * c[1] - c[2], 0, 255);
- return result;
-}
-
-// This is the 'bit_transfer_signed' function defined in Section C.2.14 of the
-// ASTC specification.
-void BitTransferSigned(int* const a, int* const b) {
- *b >>= 1;
- *b |= *a & 0x80;
- *a >>= 1;
- *a &= 0x3F;
- if ((*a & 0x20) != 0) {
- *a -= 0x40;
- }
-}
-
-// Takes two values, |a| in the range [-32, 31], and |b| in the range [0, 255],
-// and returns the two values in [0, 255] that will reconstruct |a| and |b| when
-// passed to the BitTransferSigned function.
-void InvertBitTransferSigned(int* const a, int* const b) {
- assert(*a >= -32); assert(*a < 32);
- assert(*b >= 0); assert(*b < 256);
-
- if (*a < 0) {
- *a += 0x40;
- }
- *a <<= 1;
- *a |= (*b & 0x80);
- *b <<= 1;
- *b &= 0xff;
-}
-
-RgbColor StripAlpha(const RgbaColor& c) {
- return RgbColor {{ c[0], c[1], c[2] }};
-}
-
-template<typename ContainerType>
-void Quantize(ContainerType* const c, size_t max_value) {
- for (auto& x : *c) {
- x = QuantizeCEValueToRange(x, max_value);
- }
-}
-
-template<typename ArrayType>
-ArrayType QuantizeColor(const ArrayType& c, size_t max_value) {
- ArrayType result = c;
- Quantize(&result, max_value);
- return result;
-}
-
-template<typename ContainerType>
-void Unquantize(ContainerType* const c, size_t max_value) {
- for (auto& x : *c) {
- x = UnquantizeCEValueFromRange(x, max_value);
- }
-}
-
-template<typename ArrayType>
-ArrayType UnquantizeColor(const ArrayType& c, size_t max_value) {
- ArrayType result = c;
- Unquantize(&result, max_value);
- return result;
-}
-
-// Returns the average of the three RGB channels.
-template<typename ContainerType>
-const int AverageRGB(const ContainerType& c) {
- // Each channel can be in the range [0, 255], and we need to divide by three.
- // However, we want to round the error properly. Both (x + 1) / 3 and
- // (x + 2) / 3 are relatively imprecise when it comes to rounding, so instead
- // we increase the precision by multiplying our numerator by some arbitrary
- // number. Here, we choose 256 to get 8 additional bits and maintain
- // performance since it turns into a shift rather than a multiply. Our
- // denominator then becomes 3 * 256 = 768.
- return (std::accumulate(c.begin(), c.begin() + 3, 0) * 256 + 384) / 768;
-}
-
-// Returns the sum of squared differences between each element of |a| and |b|,
-// which are assumed to contain the same number of elements.
-template<typename ContainerType>
-const typename ContainerType::value_type SquaredError(
- const ContainerType& a, const ContainerType& b,
- size_t num_channels = std::tuple_size<ContainerType>::value) {
- using ValueTy = typename ContainerType::value_type;
- static_assert(std::is_signed<ValueTy>::value,
- "Value type assumed to be signed to avoid branch below.");
- ValueTy result = ValueTy(0);
- for (int i = 0; i < num_channels; ++i) {
- ValueTy error = a[i] - b[i];
- result += error * error;
- }
- return result;
-}
-
-constexpr int MaxValuesForModes(ColorEndpointMode mode_a,
- ColorEndpointMode mode_b) {
- return (NumColorValuesForEndpointMode(mode_a) >
- NumColorValuesForEndpointMode(mode_b))
- ? NumColorValuesForEndpointMode(mode_a)
- : NumColorValuesForEndpointMode(mode_b);
-}
-
-// This function takes the two colors in |endpoint_low| and |endpoint_high| and
-// encodes them into |vals| according to the ASTC spec in section C.2.14. It
-// assumes that the two colors are close enough to grayscale that the encoding
-// should use the ColorEndpointMode kLDRLumaBaseOffset or kLDRLumaDirect. Which
-// one is chosen depends on which produces smaller error for the given
-// quantization value stored in |max_value|
-bool EncodeColorsLuma(const RgbaColor& endpoint_low,
- const RgbaColor& endpoint_high,
- int max_value, ColorEndpointMode* const astc_mode,
- std::vector<int>* const vals) {
- assert(vals->size() ==
- NumValuesForEncodingMode(EndpointEncodingMode::kDirectLuma));
- int avg1 = AverageRGB(endpoint_low);
- int avg2 = AverageRGB(endpoint_high);
-
- // For the offset mode, L1 is strictly greater than L2, so if we are using
- // it to encode the color values, we need to swap the weights and
- // endpoints so that the larger of the two is the second endpoint.
- bool needs_weight_swap = false;
- if (avg1 > avg2) {
- needs_weight_swap = true;
- std::swap(avg1, avg2);
- }
- assert(avg1 <= avg2);
-
- // Now, the first endpoint is based on the low-order six bits of the first
- // value, and the high order two bits of the second value. The low order
- // six bits of the second value are used as the (strictly positive) offset
- // from the first value.
- const int offset = std::min(avg2 - avg1, 0x3F);
- const int quant_off_low =
- QuantizeCEValueToRange((avg1 & 0x3F) << 2, max_value);
- const int quant_off_high =
- QuantizeCEValueToRange((avg1 & 0xC0) | offset, max_value);
-
- const int quant_low = QuantizeCEValueToRange(avg1, max_value);
- const int quant_high = QuantizeCEValueToRange(avg2, max_value);
-
- RgbaColor unquant_off_low, unquant_off_high;
- RgbaColor unquant_low, unquant_high;
-
- (*vals)[0] = quant_off_low;
- (*vals)[1] = quant_off_high;
- DecodeColorsForMode(
- *vals, max_value, ColorEndpointMode::kLDRLumaBaseOffset,
- &unquant_off_low, &unquant_off_high);
-
- (*vals)[0] = quant_low;
- (*vals)[1] = quant_high;
- DecodeColorsForMode(*vals, max_value, ColorEndpointMode::kLDRLumaDirect,
- &unquant_low, &unquant_high);
-
- const auto calculate_error =
- [needs_weight_swap, &endpoint_low, &endpoint_high]
- (const RgbaColor& low, const RgbaColor& high) {
- int error = 0;
- if (needs_weight_swap) {
- error += SquaredError(low, endpoint_high);
- error += SquaredError(high, endpoint_low);
- } else {
- error += SquaredError(low, endpoint_low);
- error += SquaredError(high, endpoint_high);
- }
- return error;
- };
-
- const int direct_error = calculate_error(unquant_low, unquant_high);
- const int off_error = calculate_error(unquant_off_low, unquant_off_high);
-
- if (direct_error <= off_error) {
- (*vals)[0] = quant_low;
- (*vals)[1] = quant_high;
- *astc_mode = ColorEndpointMode::kLDRLumaDirect;
- } else {
- (*vals)[0] = quant_off_low;
- (*vals)[1] = quant_off_high;
- *astc_mode = ColorEndpointMode::kLDRLumaBaseOffset;
- }
-
- return needs_weight_swap;
-}
-
-class QuantizedEndpointPair {
- public:
- QuantizedEndpointPair(const RgbaColor& c_low, const RgbaColor& c_high,
- int max_value)
- : orig_low_(c_low),
- orig_high_(c_high),
- quant_low_(QuantizeColor(c_low, max_value)),
- quant_high_(QuantizeColor(c_high, max_value)),
- unquant_low_(UnquantizeColor(quant_low_, max_value)),
- unquant_high_(UnquantizeColor(quant_high_, max_value)) { }
-
- const RgbaColor& QuantizedLow() const { return quant_low_; }
- const RgbaColor& QuantizedHigh() const { return quant_high_; }
-
- const RgbaColor& UnquantizedLow() const { return unquant_low_; }
- const RgbaColor& UnquantizedHigh() const { return unquant_high_; }
-
- const RgbaColor& OriginalLow() const { return orig_low_; }
- const RgbaColor& OriginalHigh() const { return orig_high_; }
-
- private:
- RgbaColor orig_low_;
- RgbaColor orig_high_;
-
- RgbaColor quant_low_;
- RgbaColor quant_high_;
-
- RgbaColor unquant_low_;
- RgbaColor unquant_high_;
-};
-
-class CEEncodingOption {
- public:
- CEEncodingOption() { }
- CEEncodingOption(
- int squared_error, const QuantizedEndpointPair* quantized_endpoints,
- bool swap_endpoints, bool blue_contract, bool use_offset_mode)
- : squared_error_(squared_error),
- quantized_endpoints_(quantized_endpoints),
- swap_endpoints_(swap_endpoints),
- blue_contract_(blue_contract),
- use_offset_mode_(use_offset_mode) { }
-
- // Returns true if able to generate valid |astc_mode| and |vals|. In some
- // instances, such as if the endpoints reprsent a base/offset pair, we may not
- // be able to guarantee blue-contract encoding due to how the base/offset pair
- // are represented and the specifics of the decoding procedure. Similarly,
- // some direct RGBA encodings also may not be able to emit blue-contract modes
- // due to an unlucky combination of channels. In these instances, this
- // function will return false, and all pointers will remain unmodified.
- bool Pack(bool with_alpha, ColorEndpointMode* const astc_mode,
- std::vector<int>* const vals, bool* const needs_weight_swap) const {
- auto unquantized_low = quantized_endpoints_->UnquantizedLow();
- auto unquantized_high = quantized_endpoints_->UnquantizedHigh();
-
- // In offset mode, we do BitTransferSigned before analyzing the values
- // of the endpoints in order to determine whether or not we're going to
- // be using blue-contract mode.
- if (use_offset_mode_) {
- for (int i = 0; i < std::tuple_size<RgbaColor>::value; ++i) {
- BitTransferSigned(&unquantized_high[i], &unquantized_low[i]);
- }
- }
-
- // Define variables as outlined in the ASTC spec C.2.14 for the RGB[A]
- // direct and base-offset modes
- int s0 = 0, s1 = 0;
- for (int i = 0; i < 3; ++i) {
- s0 += unquantized_low[i];
- s1 += unquantized_high[i];
- }
-
- // Can we guarantee a blue-contract mode if we want it? In other words,
- // if we swap which endpoint is high and which endpoint is low, can we
- // guarantee that we will hit the corresponding decode path?
- bool swap_vals = false;
- if (use_offset_mode_) {
- if (blue_contract_) {
- swap_vals = s1 >= 0;
- } else {
- swap_vals = s1 < 0;
- }
-
- // In offset mode, we have two different measurements that swap the
- // endpoints prior to encoding, so we don't need to swap them here.
- // If we need to swap them to guarantee a blue-contract mode, then
- // abort and wait until we get the other error measurement.
- if (swap_vals) {
- return false;
- }
- } else {
- if (blue_contract_) {
- // If we want a blue_contract path, but s1 == s0, then swapping the
- // values will have no effect.
- if (s1 == s0) {
- return false;
- }
-
- swap_vals = s1 > s0;
- // If we're encoding blue contract mode directly, then we implicitly
- // swap the endpoints during decode, meaning that we need to take
- // note of that here.
- *needs_weight_swap = !(*needs_weight_swap);
- } else {
- swap_vals = s1 < s0;
- }
- }
-
- const auto* quantized_low = &(quantized_endpoints_->QuantizedLow());
- const auto* quantized_high = &(quantized_endpoints_->QuantizedHigh());
-
- if (swap_vals) {
- assert(!use_offset_mode_);
- std::swap(quantized_low, quantized_high);
- *needs_weight_swap = !(*needs_weight_swap);
- }
-
- (*vals)[0] = quantized_low->at(0);
- (*vals)[1] = quantized_high->at(0);
- (*vals)[2] = quantized_low->at(1);
- (*vals)[3] = quantized_high->at(1);
- (*vals)[4] = quantized_low->at(2);
- (*vals)[5] = quantized_high->at(2);
-
- if (use_offset_mode_) {
- *astc_mode = ColorEndpointMode::kLDRRGBBaseOffset;
- } else {
- *astc_mode = ColorEndpointMode::kLDRRGBDirect;
- }
-
- if (with_alpha) {
- (*vals)[6] = quantized_low->at(3);
- (*vals)[7] = quantized_high->at(3);
-
- if (use_offset_mode_) {
- *astc_mode = ColorEndpointMode::kLDRRGBABaseOffset;
- } else {
- *astc_mode = ColorEndpointMode::kLDRRGBADirect;
- }
- }
-
- // If we swapped them to measure, then they need to be swapped after
- // decoding
- if (swap_endpoints_) {
- *needs_weight_swap = !(*needs_weight_swap);
- }
-
- return true;
- }
-
- bool BlueContract() const { return blue_contract_; }
- int Error() const { return squared_error_; }
-
- private:
- int squared_error_;
- const QuantizedEndpointPair* quantized_endpoints_;
- bool swap_endpoints_;
- bool blue_contract_;
- bool use_offset_mode_;
-};
-
-bool EncodeColorsRGBA(const RgbaColor& endpoint_low_rgba,
- const RgbaColor& endpoint_high_rgba,
- int max_value, bool with_alpha,
- ColorEndpointMode* const astc_mode,
- std::vector<int>* const vals) {
- const int num_channels = with_alpha ? std::tuple_size<RgbaColor>::value : 3;
- // The difficulty of encoding into this mode is determining whether or
- // not we'd like to use the 'blue contract' function to reconstruct
- // the endpoints and whether or not we'll be more accurate by using the
- // base/offset color modes instead of quantizing the color channels
- // directly. With that in mind, we:
- // 1. Generate the inverted values for blue-contract and offset modes.
- // 2. Quantize all of the different endpoints.
- // 3. Unquantize each sets and decide which one gives least error
- // 4. Encode the values correspondingly.
-
- // 1. Generate the inverted values for blue-contract and offset modes.
- const auto inv_bc_low = InvertBlueContract(endpoint_low_rgba);
- const auto inv_bc_high = InvertBlueContract(endpoint_high_rgba);
-
- RgbaColor direct_base, direct_offset;
- for (int i = 0; i < std::tuple_size<RgbaColor>::value; ++i) {
- direct_base[i] = endpoint_low_rgba[i];
- direct_offset[i] =
- Clamp(endpoint_high_rgba[i] - endpoint_low_rgba[i], -32, 31);
- InvertBitTransferSigned(&direct_offset[i], &direct_base[i]);
- }
-
- RgbaColor inv_bc_base, inv_bc_offset;
- for (int i = 0; i < std::tuple_size<RgbaColor>::value; ++i) {
- // Remember, for blue-contract'd offset modes, the base is compared
- // against the second endpoint and not the first.
- inv_bc_base[i] = inv_bc_high[i];
- inv_bc_offset[i] = Clamp(inv_bc_low[i] - inv_bc_high[i], -32, 31);
- InvertBitTransferSigned(&inv_bc_offset[i], &inv_bc_base[i]);
- }
-
- // The order of the endpoints for offset modes may determine how well they
- // approximate the given endpoints. It may be that the quantization value
- // produces more accurate values for the base than the offset or
- // vice/versa. For this reason, we need to generate quantized versions of
- // the endpoints as if they were swapped to see if we get better error
- // out of it.
-
- RgbaColor direct_base_swapped, direct_offset_swapped;
- for (int i = 0; i < std::tuple_size<RgbaColor>::value; ++i) {
- direct_base_swapped[i] = endpoint_high_rgba[i];
- direct_offset_swapped[i] =
- Clamp(endpoint_low_rgba[i] - endpoint_high_rgba[i], -32, 31);
- InvertBitTransferSigned(&direct_offset_swapped[i], &direct_base_swapped[i]);
- }
-
- RgbaColor inv_bc_base_swapped, inv_bc_offset_swapped;
- for (int i = 0; i < std::tuple_size<RgbaColor>::value; ++i) {
- // Remember, for blue-contract'd offset modes, the base is compared
- // against the second endpoint and not the first. Hence, the swapped
- // version will compare the base against the first endpoint.
- inv_bc_base_swapped[i] = inv_bc_low[i];
- inv_bc_offset_swapped[i] = Clamp(inv_bc_high[i] - inv_bc_low[i], -32, 31);
- InvertBitTransferSigned(&inv_bc_offset_swapped[i], &inv_bc_base_swapped[i]);
- }
-
- // 2. Quantize the endpoints directly.
- const QuantizedEndpointPair direct_quantized(
- endpoint_low_rgba, endpoint_high_rgba, max_value);
- const QuantizedEndpointPair bc_quantized(
- inv_bc_low, inv_bc_high, max_value);
-
- const QuantizedEndpointPair offset_quantized(
- direct_base, direct_offset, max_value);
- const QuantizedEndpointPair bc_offset_quantized(
- inv_bc_base, inv_bc_offset, max_value);
-
- const QuantizedEndpointPair offset_swapped_quantized(
- direct_base_swapped, direct_offset_swapped, max_value);
- const QuantizedEndpointPair bc_offset_swapped_quantized(
- inv_bc_base_swapped, inv_bc_offset_swapped, max_value);
-
- // 3. Unquantize each set and decide which one gives least error.
- std::array<CEEncodingOption, 6> errors;
- auto errors_itr = errors.begin();
-
- // 3.1 regular unquantized error
- {
- const auto rgba_low = direct_quantized.UnquantizedLow();
- const auto rgba_high = direct_quantized.UnquantizedHigh();
-
- const int sq_rgb_error =
- SquaredError(rgba_low, endpoint_low_rgba, num_channels) +
- SquaredError(rgba_high, endpoint_high_rgba, num_channels);
-
- const bool swap_endpoints = false;
- const bool blue_contract = false;
- const bool offset_mode = false;
- *(errors_itr++) = CEEncodingOption(
- sq_rgb_error, &direct_quantized,
- swap_endpoints, blue_contract, offset_mode);
- }
-
- // 3.2 Compute blue-contract'd error.
- {
- auto bc_low = bc_quantized.UnquantizedLow();
- auto bc_high = bc_quantized.UnquantizedHigh();
- BlueContract(&bc_low);
- BlueContract(&bc_high);
-
- const int sq_bc_error =
- SquaredError(bc_low, endpoint_low_rgba, num_channels) +
- SquaredError(bc_high, endpoint_high_rgba, num_channels);
-
- const bool swap_endpoints = false;
- const bool blue_contract = true;
- const bool offset_mode = false;
- *(errors_itr++) = CEEncodingOption(
- sq_bc_error, &bc_quantized,
- swap_endpoints, blue_contract, offset_mode);
- }
-
- // 3.3 Compute base/offset unquantized error.
- const auto compute_base_offset_error =
- [num_channels, &errors_itr, &endpoint_low_rgba, &endpoint_high_rgba]
- (const QuantizedEndpointPair& pair, bool swapped) {
- auto base = pair.UnquantizedLow();
- auto offset = pair.UnquantizedHigh();
-
- for (int i = 0; i < num_channels; ++i) {
- BitTransferSigned(&offset[i], &base[i]);
- offset[i] = Clamp(base[i] + offset[i], 0, 255);
- }
-
- int base_offset_error = 0;
- // If we swapped the endpoints going in, then without blue contract
- // we should be comparing the base against the high endpoint.
- if (swapped) {
- base_offset_error =
- SquaredError(base, endpoint_high_rgba, num_channels) +
- SquaredError(offset, endpoint_low_rgba, num_channels);
- } else {
- base_offset_error =
- SquaredError(base, endpoint_low_rgba, num_channels) +
- SquaredError(offset, endpoint_high_rgba, num_channels);
- }
-
- const bool blue_contract = false;
- const bool offset_mode = true;
- *(errors_itr++) = CEEncodingOption(
- base_offset_error, &pair, swapped, blue_contract, offset_mode);
- };
-
- compute_base_offset_error(offset_quantized, false);
-
- // 3.4 Compute base/offset blue-contract error.
- const auto compute_base_offset_blue_contract_error =
- [num_channels, &errors_itr, &endpoint_low_rgba, &endpoint_high_rgba]
- (const QuantizedEndpointPair& pair, bool swapped) {
- auto base = pair.UnquantizedLow();
- auto offset = pair.UnquantizedHigh();
-
- for (int i = 0; i < num_channels; ++i) {
- BitTransferSigned(&offset[i], &base[i]);
- offset[i] = Clamp(base[i] + offset[i], 0, 255);
- }
-
- BlueContract(&base);
- BlueContract(&offset);
-
- int sq_bc_error = 0;
- // Remember, for blue-contract'd offset modes, the base is compared
- // against the second endpoint and not the first. So, we compare
- // against the first if we swapped the endpoints going in.
- if (swapped) {
- sq_bc_error =
- SquaredError(base, endpoint_low_rgba, num_channels) +
- SquaredError(offset, endpoint_high_rgba, num_channels);
- } else {
- sq_bc_error =
- SquaredError(base, endpoint_high_rgba, num_channels) +
- SquaredError(offset, endpoint_low_rgba, num_channels);
- }
-
- const bool blue_contract = true;
- const bool offset_mode = true;
- *(errors_itr++) = CEEncodingOption(sq_bc_error, &pair,
- swapped, blue_contract, offset_mode);
- };
-
- compute_base_offset_blue_contract_error(bc_offset_quantized, false);
-
- // 3.5 Compute swapped base/offset error.
- compute_base_offset_error(offset_swapped_quantized, true);
-
- // 3.6 Compute swapped base/offset blue-contract error.
- compute_base_offset_blue_contract_error(
- bc_offset_swapped_quantized, true);
-
- std::sort(errors.begin(), errors.end(),
- [](const CEEncodingOption& a, const CEEncodingOption& b) {
- return a.Error() < b.Error();
- });
-
- // 4. Encode the values correspondingly.
- // For this part, we go through each measurement in order of increasing
- // error. Based on the properties of each measurement, we decide how to
- // best encode the quantized endpoints that produced that error value. If
- // for some reason we cannot encode that metric, then we skip it and move
- // to the next one.
- for (const auto& measurement : errors) {
- bool needs_weight_swap = false;
- if (measurement.Pack(with_alpha, astc_mode, vals, &needs_weight_swap)) {
- // Make sure that if we ask for a blue-contract mode that we get it *and*
- // if we don't ask for it then we don't get it.
- assert(!(measurement.BlueContract() ^
- UsesBlueContract(max_value, *astc_mode, *vals)));
-
- // We encoded what we got.
- return needs_weight_swap;
- }
- }
-
- assert(false && "Shouldn't have reached this point -- some combination of "
- "endpoints should be possible to encode!");
- return false;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool UsesBlueContract(int max_value, ColorEndpointMode mode,
- const std::vector<int>& vals) {
- assert(vals.size() >= NumColorValuesForEndpointMode(mode));
-
- switch (mode) {
- case ColorEndpointMode::kLDRRGBDirect:
- case ColorEndpointMode::kLDRRGBADirect: {
- constexpr int kNumVals = MaxValuesForModes(
- ColorEndpointMode::kLDRRGBDirect, ColorEndpointMode::kLDRRGBADirect);
- std::array<int, kNumVals> v {};
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- const int s0 = v[0] + v[2] + v[4];
- const int s1 = v[1] + v[3] + v[5];
-
- return s0 > s1;
- }
-
- case ColorEndpointMode::kLDRRGBBaseOffset:
- case ColorEndpointMode::kLDRRGBABaseOffset: {
- constexpr int kNumVals = MaxValuesForModes(
- ColorEndpointMode::kLDRRGBBaseOffset,
- ColorEndpointMode::kLDRRGBABaseOffset);
- std::array<int, kNumVals> v {};
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- BitTransferSigned(&v[1], &v[0]);
- BitTransferSigned(&v[3], &v[2]);
- BitTransferSigned(&v[5], &v[4]);
-
- return v[1] + v[3] + v[5] < 0;
- }
-
- default:
- return false;
- }
-}
-
-bool EncodeColorsForMode(
- const RgbaColor& endpoint_low_rgba, const RgbaColor& endpoint_high_rgba,
- int max_value, EndpointEncodingMode encoding_mode,
- ColorEndpointMode* const astc_mode, std::vector<int>* const vals) {
- bool needs_weight_swap = false;
- vals->resize(NumValuesForEncodingMode(encoding_mode));
-
- switch (encoding_mode) {
- case EndpointEncodingMode::kDirectLuma:
- return EncodeColorsLuma(
- endpoint_low_rgba, endpoint_high_rgba, max_value, astc_mode, vals);
-
- case EndpointEncodingMode::kDirectLumaAlpha: {
- // TODO(google): See if luma-alpha base-offset is better
- const int avg1 = AverageRGB(endpoint_low_rgba);
- const int avg2 = AverageRGB(endpoint_high_rgba);
-
- (*vals)[0] = QuantizeCEValueToRange(avg1, max_value);
- (*vals)[1] = QuantizeCEValueToRange(avg2, max_value);
- (*vals)[2] = QuantizeCEValueToRange(endpoint_low_rgba[3], max_value);
- (*vals)[3] = QuantizeCEValueToRange(endpoint_high_rgba[3], max_value);
- *astc_mode = ColorEndpointMode::kLDRLumaAlphaDirect;
- }
- break;
-
- case EndpointEncodingMode::kBaseScaleRGB:
- case EndpointEncodingMode::kBaseScaleRGBA: {
- RgbaColor base = endpoint_high_rgba;
- RgbaColor scaled = endpoint_low_rgba;
-
- // Similar to luma base-offset, the scaled value is strictly less than
- // the base value here according to the decode procedure. In this case,
- // if the base is larger than the scale then we need to swap.
- int num_channels_ge = 0;
- for (int i = 0; i < 3; ++i) {
- num_channels_ge +=
- static_cast<int>(endpoint_high_rgba[i] >= endpoint_low_rgba[i]);
- }
-
- if (num_channels_ge < 2) {
- needs_weight_swap = true;
- std::swap(base, scaled);
- }
-
- // Since the second endpoint is just a direct copy of the RGB values, we
- // can start by quantizing them.
- const auto q_base = QuantizeColor(base, max_value);
- const auto uq_base = UnquantizeColor(q_base, max_value);
-
- // The first endpoint (scaled) is defined by piecewise multiplying the
- // second endpoint (base) by the scale factor and then dividing by 256.
- // This means that the inverse operation is to first piecewise multiply
- // the first endpoint by 256 and then divide by the unquantized second
- // endpoint. We take the average of each of each of these scale values as
- // our final scale value.
- // TODO(google): Is this the best way to determine the scale factor?
- int num_samples = 0;
- int scale_sum = 0;
- for (int i = 0; i < 3; ++i) {
- int x = uq_base[i];
- if (x != 0) {
- ++num_samples;
- scale_sum += (scaled[i] * 256) / x;
- }
- }
-
- (*vals)[0] = q_base[0];
- (*vals)[1] = q_base[1];
- (*vals)[2] = q_base[2];
- if (num_samples > 0) {
- const int avg_scale = Clamp(scale_sum / num_samples, 0, 255);
- (*vals)[3] = QuantizeCEValueToRange(avg_scale, max_value);
- } else {
- // In this case, all of the base values are zero, so we can use whatever
- // we want as the scale -- it won't affect the outcome.
- (*vals)[3] = max_value;
- }
- *astc_mode = ColorEndpointMode::kLDRRGBBaseScale;
-
- if (encoding_mode == EndpointEncodingMode::kBaseScaleRGBA) {
- (*vals)[4] = QuantizeCEValueToRange(scaled[3], max_value);
- (*vals)[5] = QuantizeCEValueToRange(base[3], max_value);
- *astc_mode = ColorEndpointMode::kLDRRGBBaseScaleTwoA;
- }
- }
- break;
-
- case EndpointEncodingMode::kDirectRGB:
- case EndpointEncodingMode::kDirectRGBA:
- return EncodeColorsRGBA(
- endpoint_low_rgba, endpoint_high_rgba, max_value,
- encoding_mode == EndpointEncodingMode::kDirectRGBA, astc_mode, vals);
-
- default:
- assert(false && "Unimplemented color encoding.");
- }
-
- return needs_weight_swap;
-}
-
-// These decoding procedures follow the code outlined in Section C.2.14 of
-// the ASTC specification.
-void DecodeColorsForMode(const std::vector<int>& vals,
- int max_value, ColorEndpointMode mode,
- RgbaColor* const endpoint_low_rgba,
- RgbaColor* const endpoint_high_rgba) {
- assert(vals.size() >= NumColorValuesForEndpointMode(mode));
- switch (mode) {
- case ColorEndpointMode::kLDRLumaDirect: {
- const int l0 = UnquantizeCEValueFromRange(vals[0], max_value);
- const int l1 = UnquantizeCEValueFromRange(vals[1], max_value);
-
- *endpoint_low_rgba = {{ l0, l0, l0, 255 }};
- *endpoint_high_rgba = {{ l1, l1, l1, 255 }};
- }
- break;
-
- case ColorEndpointMode::kLDRLumaBaseOffset: {
- const int v0 = UnquantizeCEValueFromRange(vals[0], max_value);
- const int v1 = UnquantizeCEValueFromRange(vals[1], max_value);
-
- const int l0 = (v0 >> 2) | (v1 & 0xC0);
- const int l1 = std::min(l0 + (v1 & 0x3F), 0xFF);
-
- *endpoint_low_rgba = {{ l0, l0, l0, 255 }};
- *endpoint_high_rgba = {{ l1, l1, l1, 255 }};
- }
- break;
-
- case ColorEndpointMode::kLDRLumaAlphaDirect: {
- constexpr int kNumVals =
- NumColorValuesForEndpointMode(ColorEndpointMode::kLDRLumaAlphaDirect);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- *endpoint_low_rgba = {{ v[0], v[0], v[0], v[2] }};
- *endpoint_high_rgba = {{ v[1], v[1], v[1], v[3] }};
- }
- break;
-
- case ColorEndpointMode::kLDRLumaAlphaBaseOffset: {
- constexpr int kNumVals = NumColorValuesForEndpointMode(
- ColorEndpointMode::kLDRLumaAlphaBaseOffset);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- BitTransferSigned(&v[1], &v[0]);
- BitTransferSigned(&v[3], &v[2]);
-
- *endpoint_low_rgba = {{ v[0], v[0], v[0], v[2] }};
- const int high_luma = v[0] + v[1];
- *endpoint_high_rgba = {{ high_luma, high_luma, high_luma, v[2] + v[3] }};
-
- for (auto& c : *endpoint_low_rgba) { c = Clamp(c, 0, 255); }
- for (auto& c : *endpoint_high_rgba) { c = Clamp(c, 0, 255); }
- }
- break;
-
- case ColorEndpointMode::kLDRRGBBaseScale: {
- constexpr int kNumVals =
- NumColorValuesForEndpointMode(ColorEndpointMode::kLDRRGBBaseScale);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- *endpoint_high_rgba = {{ v[0], v[1], v[2], 255 }};
- for (int i = 0; i < 3; ++i) {
- const int x = endpoint_high_rgba->at(i);
- endpoint_low_rgba->at(i) = (x * v[3]) >> 8;
- }
- endpoint_low_rgba->at(3) = 255;
- }
- break;
-
- case ColorEndpointMode::kLDRRGBDirect: {
- constexpr int kNumVals =
- NumColorValuesForEndpointMode(ColorEndpointMode::kLDRRGBDirect);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- const int s0 = v[0] + v[2] + v[4];
- const int s1 = v[1] + v[3] + v[5];
-
- *endpoint_low_rgba = {{ v[0], v[2], v[4], 255 }};
- *endpoint_high_rgba = {{ v[1], v[3], v[5], 255 }};
-
- if (s1 < s0) {
- std::swap(*endpoint_low_rgba, *endpoint_high_rgba);
- BlueContract(endpoint_low_rgba);
- BlueContract(endpoint_high_rgba);
- }
- }
- break;
-
- case ColorEndpointMode::kLDRRGBBaseOffset: {
- constexpr int kNumVals =
- NumColorValuesForEndpointMode(ColorEndpointMode::kLDRRGBBaseOffset);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- BitTransferSigned(&v[1], &v[0]);
- BitTransferSigned(&v[3], &v[2]);
- BitTransferSigned(&v[5], &v[4]);
-
- *endpoint_low_rgba = {{ v[0], v[2], v[4], 255 }};
- *endpoint_high_rgba = {{ v[0] + v[1], v[2] + v[3], v[4] + v[5], 255 }};
-
- if (v[1] + v[3] + v[5] < 0) {
- std::swap(*endpoint_low_rgba, *endpoint_high_rgba);
- BlueContract(endpoint_low_rgba);
- BlueContract(endpoint_high_rgba);
- }
-
- for (auto& c : *endpoint_low_rgba) { c = Clamp(c, 0, 255); }
- for (auto& c : *endpoint_high_rgba) { c = Clamp(c, 0, 255); }
- }
- break;
-
- case ColorEndpointMode::kLDRRGBBaseScaleTwoA: {
- constexpr int kNumVals = NumColorValuesForEndpointMode(
- ColorEndpointMode::kLDRRGBBaseScaleTwoA);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- // Base
- *endpoint_low_rgba = *endpoint_high_rgba = {{ v[0], v[1], v[2], 255 }};
-
- // Scale
- for (int i = 0; i < 3; ++i) {
- auto& x = endpoint_low_rgba->at(i);
- x = (x * v[3]) >> 8;
- }
-
- // Two A
- endpoint_low_rgba->at(3) = v[4];
- endpoint_high_rgba->at(3) = v[5];
- }
- break;
-
- case ColorEndpointMode::kLDRRGBADirect: {
- constexpr int kNumVals =
- NumColorValuesForEndpointMode(ColorEndpointMode::kLDRRGBADirect);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- const int s0 = v[0] + v[2] + v[4];
- const int s1 = v[1] + v[3] + v[5];
-
- *endpoint_low_rgba = {{ v[0], v[2], v[4], v[6] }};
- *endpoint_high_rgba = {{ v[1], v[3], v[5], v[7] }};
-
- if (s1 < s0) {
- std::swap(*endpoint_low_rgba, *endpoint_high_rgba);
- BlueContract(endpoint_low_rgba);
- BlueContract(endpoint_high_rgba);
- }
- }
- break;
-
- case ColorEndpointMode::kLDRRGBABaseOffset: {
- constexpr int kNumVals =
- NumColorValuesForEndpointMode(ColorEndpointMode::kLDRRGBABaseOffset);
-
- std::array<int, kNumVals> v;
- std::copy(vals.begin(), vals.end(), v.begin());
- Unquantize(&v, max_value);
-
- BitTransferSigned(&v[1], &v[0]);
- BitTransferSigned(&v[3], &v[2]);
- BitTransferSigned(&v[5], &v[4]);
- BitTransferSigned(&v[7], &v[6]);
-
- *endpoint_low_rgba = {{ v[0], v[2], v[4], v[6] }};
- *endpoint_high_rgba = {{
- v[0] + v[1], v[2] + v[3], v[4] + v[5], v[6] + v[7] }};
-
- if (v[1] + v[3] + v[5] < 0) {
- std::swap(*endpoint_low_rgba, *endpoint_high_rgba);
- BlueContract(endpoint_low_rgba);
- BlueContract(endpoint_high_rgba);
- }
-
- for (auto& c : *endpoint_low_rgba) { c = Clamp(c, 0, 255); }
- for (auto& c : *endpoint_high_rgba) { c = Clamp(c, 0, 255); }
- }
- break;
-
- default:
- // Unimplemented color encoding.
- // TODO(google): Is this the correct error handling?
- *endpoint_high_rgba = *endpoint_low_rgba = {{ 0, 0, 0, 0 }};
- }
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/endpoint_codec.h b/third-party/astc-codec/src/decoder/endpoint_codec.h
deleted file mode 100644
index a1232d06..00000000
--- a/third-party/astc-codec/src/decoder/endpoint_codec.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_ENDPOINT_CODEC_H_
-#define ASTC_CODEC_DECODER_ENDPOINT_CODEC_H_
-
-#include "src/decoder/physical_astc_block.h"
-#include "src/decoder/types.h"
-
-#include <array>
-#include <vector>
-
-namespace astc_codec {
-
-// We use a special distinction for encode modes used to pass to the
-// EncodeColorsForMode function below. The reason is that some of the color
-// modes have sub-modes (like blue-contract) that change whether or not it is
-// useful to encode an endpoint pair using one mode versus another. To avoid
-// this problem, we approach the problem of encoding by specifying some
-// high-level encoding modes. These eventually choose one of the low level
-// ColorEndpointModes from Section C.2.14 when used in EncodeColorsForMode.
-enum class EndpointEncodingMode {
- kDirectLuma,
- kDirectLumaAlpha,
- kBaseScaleRGB,
- kBaseScaleRGBA,
- kDirectRGB,
- kDirectRGBA
-};
-
-// Returns the number of values in the encoded endpoint pair after encoding
-// to a specific high-level encoding mode.
-constexpr int NumValuesForEncodingMode(EndpointEncodingMode mode) {
- return
- mode == EndpointEncodingMode::kDirectLuma ? 2 :
- mode == EndpointEncodingMode::kDirectLumaAlpha ? 4 :
- mode == EndpointEncodingMode::kBaseScaleRGB ? 4 :
- mode == EndpointEncodingMode::kBaseScaleRGBA ? 6 :
- mode == EndpointEncodingMode::kDirectRGB ? 6 : 8;
-}
-
-// Fills |vals| with the quantized endpoint colors values defined in the ASTC
-// specification. The values are quantized to the range [0, max_value]. These
-// quantization limits can be obtained by querying the associated functions in
-// integer_sequence_codec. The returned |astc_mode| will be the ASTC mode used
-// to encode the resulting sequence.
-//
-// The |encoding_mode| is used to determine the way that we encode the values.
-// Each encoding mode is used to determine which ASTC mode best corresponds
-// to the pair of endpoints. It is a necessary hint to the encoding function
-// in order to process the endpoints. Each encoding mode gurantees a certain
-// number of values generated per endpoints.
-//
-// The return value will be true if the endpoints have been switched in order to
-// reap the most benefit from the way the hardware decodes the given mode. In
-// this case, the associated weights that interpolate this color must also be
-// switched. In other words, for each w, it should change to 64 - w.
-bool EncodeColorsForMode(
- const RgbaColor& endpoint_low_rgba, const RgbaColor& endpoint_high_rgba,
- int max_value, EndpointEncodingMode encoding_mode,
- ColorEndpointMode* astc_mode, std::vector<int>* vals);
-
-// Decodes the color values quantized to the range [0, max_value] into RGBA
-// endpoints for the given mode. This function is the inverse of
-// EncodeColorsForMode -- see that function for details. This function should
-// work on all LDR endpoint modes, but no HDR modes.
-void DecodeColorsForMode(const std::vector<int>& vals,
- int max_value, ColorEndpointMode mode,
- RgbaColor* endpoint_low_rgba,
- RgbaColor* endpoint_high_rgba);
-
-// Returns true if the quantized |vals| in the range [0, max_value] use the
-// 'blue_contract' modification during decoding for the given |mode|.
-bool UsesBlueContract(int max_value, ColorEndpointMode mode,
- const std::vector<int>& vals);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_ENDPOINT_CODEC_H_
diff --git a/third-party/astc-codec/src/decoder/footprint.cc b/third-party/astc-codec/src/decoder/footprint.cc
deleted file mode 100644
index e4f076e3..00000000
--- a/third-party/astc-codec/src/decoder/footprint.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/footprint.h"
-#include "src/base/string_utils.h"
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace astc_codec {
-
-namespace {
-
-// Encodes the width and height into an integer so that we can use a switch
-// statement instead of a costly lookup map.
-constexpr int EncodeDims(int width, int height) {
- return (width << 16) | height;
-}
-
-} // namespace
-
-base::Optional<FootprintType>
-Footprint::GetValidFootprintForDimensions(int width, int height) {
- switch (EncodeDims(width, height)) {
- case EncodeDims(4, 4): return FootprintType::k4x4;
- case EncodeDims(5, 4): return FootprintType::k5x4;
- case EncodeDims(5, 5): return FootprintType::k5x5;
- case EncodeDims(6, 5): return FootprintType::k6x5;
- case EncodeDims(6, 6): return FootprintType::k6x6;
- case EncodeDims(8, 5): return FootprintType::k8x5;
- case EncodeDims(8, 6): return FootprintType::k8x6;
- case EncodeDims(8, 8): return FootprintType::k8x8;
- case EncodeDims(10, 5): return FootprintType::k10x5;
- case EncodeDims(10, 6): return FootprintType::k10x6;
- case EncodeDims(10, 8): return FootprintType::k10x8;
- case EncodeDims(10, 10): return FootprintType::k10x10;
- case EncodeDims(12, 10): return FootprintType::k12x10;
- case EncodeDims(12, 12): return FootprintType::k12x12;
- default: return {};
- }
-}
-
-int Footprint::GetWidthForFootprint(FootprintType footprint) {
- switch (footprint) {
- case FootprintType::k4x4: return 4;
- case FootprintType::k5x4: return 5;
- case FootprintType::k5x5: return 5;
- case FootprintType::k6x5: return 6;
- case FootprintType::k6x6: return 6;
- case FootprintType::k8x5: return 8;
- case FootprintType::k8x6: return 8;
- case FootprintType::k10x5: return 10;
- case FootprintType::k10x6: return 10;
- case FootprintType::k8x8: return 8;
- case FootprintType::k10x8: return 10;
- case FootprintType::k10x10: return 10;
- case FootprintType::k12x10: return 12;
- case FootprintType::k12x12: return 12;
- default:
- assert(false);
- return -1;
- }
-}
-
-int Footprint::GetHeightForFootprint(FootprintType footprint) {
- switch (footprint) {
- case FootprintType::k4x4: return 4;
- case FootprintType::k5x4: return 4;
- case FootprintType::k5x5: return 5;
- case FootprintType::k6x5: return 5;
- case FootprintType::k6x6: return 6;
- case FootprintType::k8x5: return 5;
- case FootprintType::k8x6: return 6;
- case FootprintType::k10x5: return 5;
- case FootprintType::k10x6: return 6;
- case FootprintType::k8x8: return 8;
- case FootprintType::k10x8: return 8;
- case FootprintType::k10x10: return 10;
- case FootprintType::k12x10: return 10;
- case FootprintType::k12x12: return 12;
- default:
- assert(false);
- return -1;
- }
-}
-
-Footprint::Footprint(FootprintType footprint)
- : footprint_(footprint), width_(GetWidthForFootprint(footprint)),
- height_(GetHeightForFootprint(footprint)) { }
-
-////////////////////////////////////////////////////////////////////////////////
-
-base::Optional<Footprint> Footprint::Parse(const char* footprint_string) {
- assert(footprint_string && footprint_string[0] != '\0');
-
- std::vector<std::string> dimension_strings;
- base::Split(footprint_string, "x", [&dimension_strings](std::string&& s) {
- dimension_strings.push_back(std::move(s));
- });
-
- if (dimension_strings.size() != 2) {
- assert(false && "Invalid format for footprint");
- return {};
- }
-
- const int width = base::ParseInt32(dimension_strings[0].c_str(), 0);
- const int height = base::ParseInt32(dimension_strings[1].c_str(), 0);
-
- assert(width > 0 && height > 0 && "Invalid width or height.");
-
- return FromDimensions(width, height);
-}
-
-base::Optional<Footprint> Footprint::FromDimensions(int width, int height) {
- base::Optional<FootprintType> valid_footprint =
- GetValidFootprintForDimensions(width, height);
- if (valid_footprint) {
- return Footprint(valid_footprint.value());
- } else {
- return {};
- }
-}
-
-// Returns a Footprint for the given FootprintType.
-base::Optional<Footprint> Footprint::FromFootprintType(FootprintType type) {
- if (type >= FootprintType::k4x4 && type < FootprintType::kCount) {
- return Footprint(type);
- } else {
- return {};
- }
-}
-
-size_t Footprint::StorageRequirements(int width, int height) const {
- const int blocks_wide = (width + width_ - 1) / width_;
- const int blocks_high = (height + height_ - 1) / height_;
-
- constexpr size_t kASTCBlockSizeInBytes = 16;
- return blocks_wide * blocks_high * kASTCBlockSizeInBytes;
-}
-
-// Returns bits/pixel for a given footprint.
-float Footprint::Bitrate() const {
- const int kASTCBlockBitCount = 128;
- const int footprint_pixel_count = width_ * height_;
- return static_cast<float>(kASTCBlockBitCount) /
- static_cast<float>(footprint_pixel_count);
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/footprint.h b/third-party/astc-codec/src/decoder/footprint.h
deleted file mode 100644
index 47302cc3..00000000
--- a/third-party/astc-codec/src/decoder/footprint.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_FOOTPRINT_H_
-#define ASTC_CODEC_DECODER_FOOTPRINT_H_
-
-#include "include/astc-codec/astc-codec.h"
-#include "src/base/optional.h"
-
-#include <cstddef>
-
-namespace astc_codec {
-
-// An ASTC texture can be encoded with varying choices in block size. A set of
-// predefined block sizes are specified in the ASTC specification. These are
-// referred to in the literature as "footprints" available to an encoder when
-// constructing an ASTC bitstream. This class provides various utility functions
-// for interacting with these footprints.
-class Footprint {
- public:
- Footprint() = delete;
- Footprint(const Footprint& footprint) = default;
-
- // Return the footprint type.
- FootprintType Type() const { return footprint_; }
-
- // Return logical descriptions of the dimensions.
- int Width() const { return width_; }
- int Height() const { return height_; }
-
- // Returns the number of pixels for a block with this footprint.
- int NumPixels() const { return width_ * height_; }
-
- // Returns the number of bytes needed to store an ASTC encoded image with the
- // given width and height.
- size_t StorageRequirements(int width, int height) const;
-
- // Returns the number of bits used per pixel.
- float Bitrate() const;
-
- static constexpr int NumValidFootprints() {
- return static_cast<int>(FootprintType::kCount);
- }
-
- bool operator==(const Footprint& other) const {
- return footprint_ == other.footprint_;
- }
-
- // These are the valid and available ASTC footprints.
- static Footprint Get4x4() { return Footprint(FootprintType::k4x4); }
- static Footprint Get5x4() { return Footprint(FootprintType::k5x4); }
- static Footprint Get5x5() { return Footprint(FootprintType::k5x5); }
- static Footprint Get6x5() { return Footprint(FootprintType::k6x5); }
- static Footprint Get6x6() { return Footprint(FootprintType::k6x6); }
- static Footprint Get8x5() { return Footprint(FootprintType::k8x5); }
- static Footprint Get8x6() { return Footprint(FootprintType::k8x6); }
- static Footprint Get8x8() { return Footprint(FootprintType::k8x8); }
- static Footprint Get10x5() { return Footprint(FootprintType::k10x5); }
- static Footprint Get10x6() { return Footprint(FootprintType::k10x6); }
- static Footprint Get10x8() { return Footprint(FootprintType::k10x8); }
- static Footprint Get10x10() { return Footprint(FootprintType::k10x10); }
- static Footprint Get12x10() { return Footprint(FootprintType::k12x10); }
- static Footprint Get12x12() { return Footprint(FootprintType::k12x12); }
-
- // Constructs a footprint from a string of the form "NxM", or no value if
- // width and height are not a valid footprint.
- static base::Optional<Footprint> Parse(const char* footprint_string);
-
- // Returns a footprint corresponding to a block of the given width and height,
- // or no value if it does not.
- static base::Optional<Footprint> FromDimensions(int width, int height);
-
- // Returns a Footprint for the given FootprintType.
- static base::Optional<Footprint> FromFootprintType(FootprintType type);
-
- private:
- // The only constructor.
- explicit Footprint(FootprintType footprint);
-
- // Returns the valid footprint for the width and height if possible.
- static base::Optional<FootprintType> GetValidFootprintForDimensions(
- int width, int height);
-
- // Returns the associated dimension for the given valid footprint.
- static int GetWidthForFootprint(FootprintType footprint);
- static int GetHeightForFootprint(FootprintType footprint);
-
- FootprintType footprint_;
- int width_;
- int height_;
-};
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_FOOTPRINT_H_
diff --git a/third-party/astc-codec/src/decoder/integer_sequence_codec.cc b/third-party/astc-codec/src/decoder/integer_sequence_codec.cc
deleted file mode 100644
index c2cd5119..00000000
--- a/third-party/astc-codec/src/decoder/integer_sequence_codec.cc
+++ /dev/null
@@ -1,570 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/integer_sequence_codec.h"
-#include "src/base/math_utils.h"
-#include "src/base/utils.h"
-
-#include <algorithm>
-#include <iostream>
-
-namespace astc_codec {
-
-namespace {
-
-// Tables of trit and quint encodings generated by the implementation in
-// http://cs/aosp-master/external/skia/src/utils/SkTextureCompressor_ASTC.cpp
-//
-// These tables are used to decode the blocks of values encoded using the ASTC
-// integer sequence encoding. The theory is that five trits (values that can
-// take any number in the range [0, 2]) can take on a total of 3^5 = 243 total
-// values, which can be stored in eight bits. These eight bits are used to
-// decode the five trits based on the ASTC specification in Section C.2.12.
-// For simplicity, we have stored a look-up table here so that we don't need
-// to implement the decoding logic. Similarly, seven bits are used to decode
-// three quints (since 5^3 = 125 < 128).
-static const std::array<int, 5> kTritEncodings[256] = {
- {{ 0, 0, 0, 0, 0 }}, {{ 1, 0, 0, 0, 0 }}, {{ 2, 0, 0, 0, 0 }},
- {{ 0, 0, 2, 0, 0 }}, {{ 0, 1, 0, 0, 0 }}, {{ 1, 1, 0, 0, 0 }},
- {{ 2, 1, 0, 0, 0 }}, {{ 1, 0, 2, 0, 0 }}, {{ 0, 2, 0, 0, 0 }},
- {{ 1, 2, 0, 0, 0 }}, {{ 2, 2, 0, 0, 0 }}, {{ 2, 0, 2, 0, 0 }},
- {{ 0, 2, 2, 0, 0 }}, {{ 1, 2, 2, 0, 0 }}, {{ 2, 2, 2, 0, 0 }},
- {{ 2, 0, 2, 0, 0 }}, {{ 0, 0, 1, 0, 0 }}, {{ 1, 0, 1, 0, 0 }},
- {{ 2, 0, 1, 0, 0 }}, {{ 0, 1, 2, 0, 0 }}, {{ 0, 1, 1, 0, 0 }},
- {{ 1, 1, 1, 0, 0 }}, {{ 2, 1, 1, 0, 0 }}, {{ 1, 1, 2, 0, 0 }},
- {{ 0, 2, 1, 0, 0 }}, {{ 1, 2, 1, 0, 0 }}, {{ 2, 2, 1, 0, 0 }},
- {{ 2, 1, 2, 0, 0 }}, {{ 0, 0, 0, 2, 2 }}, {{ 1, 0, 0, 2, 2 }},
- {{ 2, 0, 0, 2, 2 }}, {{ 0, 0, 2, 2, 2 }}, {{ 0, 0, 0, 1, 0 }},
- {{ 1, 0, 0, 1, 0 }}, {{ 2, 0, 0, 1, 0 }}, {{ 0, 0, 2, 1, 0 }},
- {{ 0, 1, 0, 1, 0 }}, {{ 1, 1, 0, 1, 0 }}, {{ 2, 1, 0, 1, 0 }},
- {{ 1, 0, 2, 1, 0 }}, {{ 0, 2, 0, 1, 0 }}, {{ 1, 2, 0, 1, 0 }},
- {{ 2, 2, 0, 1, 0 }}, {{ 2, 0, 2, 1, 0 }}, {{ 0, 2, 2, 1, 0 }},
- {{ 1, 2, 2, 1, 0 }}, {{ 2, 2, 2, 1, 0 }}, {{ 2, 0, 2, 1, 0 }},
- {{ 0, 0, 1, 1, 0 }}, {{ 1, 0, 1, 1, 0 }}, {{ 2, 0, 1, 1, 0 }},
- {{ 0, 1, 2, 1, 0 }}, {{ 0, 1, 1, 1, 0 }}, {{ 1, 1, 1, 1, 0 }},
- {{ 2, 1, 1, 1, 0 }}, {{ 1, 1, 2, 1, 0 }}, {{ 0, 2, 1, 1, 0 }},
- {{ 1, 2, 1, 1, 0 }}, {{ 2, 2, 1, 1, 0 }}, {{ 2, 1, 2, 1, 0 }},
- {{ 0, 1, 0, 2, 2 }}, {{ 1, 1, 0, 2, 2 }}, {{ 2, 1, 0, 2, 2 }},
- {{ 1, 0, 2, 2, 2 }}, {{ 0, 0, 0, 2, 0 }}, {{ 1, 0, 0, 2, 0 }},
- {{ 2, 0, 0, 2, 0 }}, {{ 0, 0, 2, 2, 0 }}, {{ 0, 1, 0, 2, 0 }},
- {{ 1, 1, 0, 2, 0 }}, {{ 2, 1, 0, 2, 0 }}, {{ 1, 0, 2, 2, 0 }},
- {{ 0, 2, 0, 2, 0 }}, {{ 1, 2, 0, 2, 0 }}, {{ 2, 2, 0, 2, 0 }},
- {{ 2, 0, 2, 2, 0 }}, {{ 0, 2, 2, 2, 0 }}, {{ 1, 2, 2, 2, 0 }},
- {{ 2, 2, 2, 2, 0 }}, {{ 2, 0, 2, 2, 0 }}, {{ 0, 0, 1, 2, 0 }},
- {{ 1, 0, 1, 2, 0 }}, {{ 2, 0, 1, 2, 0 }}, {{ 0, 1, 2, 2, 0 }},
- {{ 0, 1, 1, 2, 0 }}, {{ 1, 1, 1, 2, 0 }}, {{ 2, 1, 1, 2, 0 }},
- {{ 1, 1, 2, 2, 0 }}, {{ 0, 2, 1, 2, 0 }}, {{ 1, 2, 1, 2, 0 }},
- {{ 2, 2, 1, 2, 0 }}, {{ 2, 1, 2, 2, 0 }}, {{ 0, 2, 0, 2, 2 }},
- {{ 1, 2, 0, 2, 2 }}, {{ 2, 2, 0, 2, 2 }}, {{ 2, 0, 2, 2, 2 }},
- {{ 0, 0, 0, 0, 2 }}, {{ 1, 0, 0, 0, 2 }}, {{ 2, 0, 0, 0, 2 }},
- {{ 0, 0, 2, 0, 2 }}, {{ 0, 1, 0, 0, 2 }}, {{ 1, 1, 0, 0, 2 }},
- {{ 2, 1, 0, 0, 2 }}, {{ 1, 0, 2, 0, 2 }}, {{ 0, 2, 0, 0, 2 }},
- {{ 1, 2, 0, 0, 2 }}, {{ 2, 2, 0, 0, 2 }}, {{ 2, 0, 2, 0, 2 }},
- {{ 0, 2, 2, 0, 2 }}, {{ 1, 2, 2, 0, 2 }}, {{ 2, 2, 2, 0, 2 }},
- {{ 2, 0, 2, 0, 2 }}, {{ 0, 0, 1, 0, 2 }}, {{ 1, 0, 1, 0, 2 }},
- {{ 2, 0, 1, 0, 2 }}, {{ 0, 1, 2, 0, 2 }}, {{ 0, 1, 1, 0, 2 }},
- {{ 1, 1, 1, 0, 2 }}, {{ 2, 1, 1, 0, 2 }}, {{ 1, 1, 2, 0, 2 }},
- {{ 0, 2, 1, 0, 2 }}, {{ 1, 2, 1, 0, 2 }}, {{ 2, 2, 1, 0, 2 }},
- {{ 2, 1, 2, 0, 2 }}, {{ 0, 2, 2, 2, 2 }}, {{ 1, 2, 2, 2, 2 }},
- {{ 2, 2, 2, 2, 2 }}, {{ 2, 0, 2, 2, 2 }}, {{ 0, 0, 0, 0, 1 }},
- {{ 1, 0, 0, 0, 1 }}, {{ 2, 0, 0, 0, 1 }}, {{ 0, 0, 2, 0, 1 }},
- {{ 0, 1, 0, 0, 1 }}, {{ 1, 1, 0, 0, 1 }}, {{ 2, 1, 0, 0, 1 }},
- {{ 1, 0, 2, 0, 1 }}, {{ 0, 2, 0, 0, 1 }}, {{ 1, 2, 0, 0, 1 }},
- {{ 2, 2, 0, 0, 1 }}, {{ 2, 0, 2, 0, 1 }}, {{ 0, 2, 2, 0, 1 }},
- {{ 1, 2, 2, 0, 1 }}, {{ 2, 2, 2, 0, 1 }}, {{ 2, 0, 2, 0, 1 }},
- {{ 0, 0, 1, 0, 1 }}, {{ 1, 0, 1, 0, 1 }}, {{ 2, 0, 1, 0, 1 }},
- {{ 0, 1, 2, 0, 1 }}, {{ 0, 1, 1, 0, 1 }}, {{ 1, 1, 1, 0, 1 }},
- {{ 2, 1, 1, 0, 1 }}, {{ 1, 1, 2, 0, 1 }}, {{ 0, 2, 1, 0, 1 }},
- {{ 1, 2, 1, 0, 1 }}, {{ 2, 2, 1, 0, 1 }}, {{ 2, 1, 2, 0, 1 }},
- {{ 0, 0, 1, 2, 2 }}, {{ 1, 0, 1, 2, 2 }}, {{ 2, 0, 1, 2, 2 }},
- {{ 0, 1, 2, 2, 2 }}, {{ 0, 0, 0, 1, 1 }}, {{ 1, 0, 0, 1, 1 }},
- {{ 2, 0, 0, 1, 1 }}, {{ 0, 0, 2, 1, 1 }}, {{ 0, 1, 0, 1, 1 }},
- {{ 1, 1, 0, 1, 1 }}, {{ 2, 1, 0, 1, 1 }}, {{ 1, 0, 2, 1, 1 }},
- {{ 0, 2, 0, 1, 1 }}, {{ 1, 2, 0, 1, 1 }}, {{ 2, 2, 0, 1, 1 }},
- {{ 2, 0, 2, 1, 1 }}, {{ 0, 2, 2, 1, 1 }}, {{ 1, 2, 2, 1, 1 }},
- {{ 2, 2, 2, 1, 1 }}, {{ 2, 0, 2, 1, 1 }}, {{ 0, 0, 1, 1, 1 }},
- {{ 1, 0, 1, 1, 1 }}, {{ 2, 0, 1, 1, 1 }}, {{ 0, 1, 2, 1, 1 }},
- {{ 0, 1, 1, 1, 1 }}, {{ 1, 1, 1, 1, 1 }}, {{ 2, 1, 1, 1, 1 }},
- {{ 1, 1, 2, 1, 1 }}, {{ 0, 2, 1, 1, 1 }}, {{ 1, 2, 1, 1, 1 }},
- {{ 2, 2, 1, 1, 1 }}, {{ 2, 1, 2, 1, 1 }}, {{ 0, 1, 1, 2, 2 }},
- {{ 1, 1, 1, 2, 2 }}, {{ 2, 1, 1, 2, 2 }}, {{ 1, 1, 2, 2, 2 }},
- {{ 0, 0, 0, 2, 1 }}, {{ 1, 0, 0, 2, 1 }}, {{ 2, 0, 0, 2, 1 }},
- {{ 0, 0, 2, 2, 1 }}, {{ 0, 1, 0, 2, 1 }}, {{ 1, 1, 0, 2, 1 }},
- {{ 2, 1, 0, 2, 1 }}, {{ 1, 0, 2, 2, 1 }}, {{ 0, 2, 0, 2, 1 }},
- {{ 1, 2, 0, 2, 1 }}, {{ 2, 2, 0, 2, 1 }}, {{ 2, 0, 2, 2, 1 }},
- {{ 0, 2, 2, 2, 1 }}, {{ 1, 2, 2, 2, 1 }}, {{ 2, 2, 2, 2, 1 }},
- {{ 2, 0, 2, 2, 1 }}, {{ 0, 0, 1, 2, 1 }}, {{ 1, 0, 1, 2, 1 }},
- {{ 2, 0, 1, 2, 1 }}, {{ 0, 1, 2, 2, 1 }}, {{ 0, 1, 1, 2, 1 }},
- {{ 1, 1, 1, 2, 1 }}, {{ 2, 1, 1, 2, 1 }}, {{ 1, 1, 2, 2, 1 }},
- {{ 0, 2, 1, 2, 1 }}, {{ 1, 2, 1, 2, 1 }}, {{ 2, 2, 1, 2, 1 }},
- {{ 2, 1, 2, 2, 1 }}, {{ 0, 2, 1, 2, 2 }}, {{ 1, 2, 1, 2, 2 }},
- {{ 2, 2, 1, 2, 2 }}, {{ 2, 1, 2, 2, 2 }}, {{ 0, 0, 0, 1, 2 }},
- {{ 1, 0, 0, 1, 2 }}, {{ 2, 0, 0, 1, 2 }}, {{ 0, 0, 2, 1, 2 }},
- {{ 0, 1, 0, 1, 2 }}, {{ 1, 1, 0, 1, 2 }}, {{ 2, 1, 0, 1, 2 }},
- {{ 1, 0, 2, 1, 2 }}, {{ 0, 2, 0, 1, 2 }}, {{ 1, 2, 0, 1, 2 }},
- {{ 2, 2, 0, 1, 2 }}, {{ 2, 0, 2, 1, 2 }}, {{ 0, 2, 2, 1, 2 }},
- {{ 1, 2, 2, 1, 2 }}, {{ 2, 2, 2, 1, 2 }}, {{ 2, 0, 2, 1, 2 }},
- {{ 0, 0, 1, 1, 2 }}, {{ 1, 0, 1, 1, 2 }}, {{ 2, 0, 1, 1, 2 }},
- {{ 0, 1, 2, 1, 2 }}, {{ 0, 1, 1, 1, 2 }}, {{ 1, 1, 1, 1, 2 }},
- {{ 2, 1, 1, 1, 2 }}, {{ 1, 1, 2, 1, 2 }}, {{ 0, 2, 1, 1, 2 }},
- {{ 1, 2, 1, 1, 2 }}, {{ 2, 2, 1, 1, 2 }}, {{ 2, 1, 2, 1, 2 }},
- {{ 0, 2, 2, 2, 2 }}, {{ 1, 2, 2, 2, 2 }}, {{ 2, 2, 2, 2, 2 }},
- {{ 2, 1, 2, 2, 2 }}
-};
-
-static const std::array<int, 3> kQuintEncodings[128] = {
- {{ 0, 0, 0 }}, {{ 1, 0, 0 }}, {{ 2, 0, 0 }}, {{ 3, 0, 0 }}, {{ 4, 0, 0 }},
- {{ 0, 4, 0 }}, {{ 4, 4, 0 }}, {{ 4, 4, 4 }}, {{ 0, 1, 0 }}, {{ 1, 1, 0 }},
- {{ 2, 1, 0 }}, {{ 3, 1, 0 }}, {{ 4, 1, 0 }}, {{ 1, 4, 0 }}, {{ 4, 4, 1 }},
- {{ 4, 4, 4 }}, {{ 0, 2, 0 }}, {{ 1, 2, 0 }}, {{ 2, 2, 0 }}, {{ 3, 2, 0 }},
- {{ 4, 2, 0 }}, {{ 2, 4, 0 }}, {{ 4, 4, 2 }}, {{ 4, 4, 4 }}, {{ 0, 3, 0 }},
- {{ 1, 3, 0 }}, {{ 2, 3, 0 }}, {{ 3, 3, 0 }}, {{ 4, 3, 0 }}, {{ 3, 4, 0 }},
- {{ 4, 4, 3 }}, {{ 4, 4, 4 }}, {{ 0, 0, 1 }}, {{ 1, 0, 1 }}, {{ 2, 0, 1 }},
- {{ 3, 0, 1 }}, {{ 4, 0, 1 }}, {{ 0, 4, 1 }}, {{ 4, 0, 4 }}, {{ 0, 4, 4 }},
- {{ 0, 1, 1 }}, {{ 1, 1, 1 }}, {{ 2, 1, 1 }}, {{ 3, 1, 1 }}, {{ 4, 1, 1 }},
- {{ 1, 4, 1 }}, {{ 4, 1, 4 }}, {{ 1, 4, 4 }}, {{ 0, 2, 1 }}, {{ 1, 2, 1 }},
- {{ 2, 2, 1 }}, {{ 3, 2, 1 }}, {{ 4, 2, 1 }}, {{ 2, 4, 1 }}, {{ 4, 2, 4 }},
- {{ 2, 4, 4 }}, {{ 0, 3, 1 }}, {{ 1, 3, 1 }}, {{ 2, 3, 1 }}, {{ 3, 3, 1 }},
- {{ 4, 3, 1 }}, {{ 3, 4, 1 }}, {{ 4, 3, 4 }}, {{ 3, 4, 4 }}, {{ 0, 0, 2 }},
- {{ 1, 0, 2 }}, {{ 2, 0, 2 }}, {{ 3, 0, 2 }}, {{ 4, 0, 2 }}, {{ 0, 4, 2 }},
- {{ 2, 0, 4 }}, {{ 3, 0, 4 }}, {{ 0, 1, 2 }}, {{ 1, 1, 2 }}, {{ 2, 1, 2 }},
- {{ 3, 1, 2 }}, {{ 4, 1, 2 }}, {{ 1, 4, 2 }}, {{ 2, 1, 4 }}, {{ 3, 1, 4 }},
- {{ 0, 2, 2 }}, {{ 1, 2, 2 }}, {{ 2, 2, 2 }}, {{ 3, 2, 2 }}, {{ 4, 2, 2 }},
- {{ 2, 4, 2 }}, {{ 2, 2, 4 }}, {{ 3, 2, 4 }}, {{ 0, 3, 2 }}, {{ 1, 3, 2 }},
- {{ 2, 3, 2 }}, {{ 3, 3, 2 }}, {{ 4, 3, 2 }}, {{ 3, 4, 2 }}, {{ 2, 3, 4 }},
- {{ 3, 3, 4 }}, {{ 0, 0, 3 }}, {{ 1, 0, 3 }}, {{ 2, 0, 3 }}, {{ 3, 0, 3 }},
- {{ 4, 0, 3 }}, {{ 0, 4, 3 }}, {{ 0, 0, 4 }}, {{ 1, 0, 4 }}, {{ 0, 1, 3 }},
- {{ 1, 1, 3 }}, {{ 2, 1, 3 }}, {{ 3, 1, 3 }}, {{ 4, 1, 3 }}, {{ 1, 4, 3 }},
- {{ 0, 1, 4 }}, {{ 1, 1, 4 }}, {{ 0, 2, 3 }}, {{ 1, 2, 3 }}, {{ 2, 2, 3 }},
- {{ 3, 2, 3 }}, {{ 4, 2, 3 }}, {{ 2, 4, 3 }}, {{ 0, 2, 4 }}, {{ 1, 2, 4 }},
- {{ 0, 3, 3 }}, {{ 1, 3, 3 }}, {{ 2, 3, 3 }}, {{ 3, 3, 3 }}, {{ 4, 3, 3 }},
- {{ 3, 4, 3 }}, {{ 0, 3, 4 }}, {{ 1, 3, 4 }}
-};
-
-// A cached table containing the max ranges for values encoded using ASTC's
-// Bounded Integer Sequence Encoding. These are the numbers between 1 and 255
-// that can be represented exactly as a number in the ranges
-// [0, 2^k), [0, 3 * 2^k), and [0, 5 * 2^k).
-static const std::array<int, kNumPossibleRanges> kMaxRanges = []() {
- std::array<int, kNumPossibleRanges> ranges;
-
- // Initialize the table that we need for determining value encodings.
- auto next_max_range = ranges.begin();
- auto add_val = [&next_max_range](int val) {
- if (val <= 0 || (1 << kLog2MaxRangeForBits) <= val) {
- return;
- }
-
- *(next_max_range++) = val;
- };
-
- for (int i = 0; i <= kLog2MaxRangeForBits; ++i) {
- add_val(3 * (1 << i) - 1);
- add_val(5 * (1 << i) - 1);
- add_val((1 << i) - 1);
- }
-
- assert(std::distance(next_max_range, ranges.end()) == 0);
- std::sort(ranges.begin(), ranges.end());
- return ranges;
-}();
-
-// Returns true if x == 0 or if x is a power of two. This function is only used
-// in the GetCountsForRange function, where we need to have it return true
-// on zero since we can have single trit/quint ISE encodings according to
-// Table C.2.7.
-template<typename T,
- typename std::enable_if<std::is_integral<T>::value, T>::type = 0>
-inline constexpr bool IsPow2(T x) { return (x & (x - 1)) == 0; }
-
-// For the ISE block encoding, these arrays determine how many bits are
-// used after each value to store the interleaved quint/trit block.
-const int kInterleavedQuintBits[3] = { 3, 2, 2 };
-const int kInterleavedTritBits[5] = { 2, 2, 1, 2, 1 };
-
-// Some template meta programming to get around the fact that MSVC
-// will not allow (ValRange == 5) ? 3 : 5 as a template parameter
-template<int ValRange>
-struct DecodeBlockSize {
- enum { value = (ValRange == 5 ? 3 : 5) };
-};
-
-// Decodes either a trit or quint block using the BISE (Bounded Integer Sequence
-// Encoding) defined in Section C.2.12 of the ASTC specification. ValRange is
-// expected to be either 3 or 5 depending on whether or not we're encoding trits
-// or quints respectively. In other words, it is the remaining factor in whether
-// the passed blocks contain encoded values of the form 3*2^k or 5*2^k.
-template<int ValRange>
-std::array<int, /* kNumVals = */ DecodeBlockSize<ValRange>::value> DecodeISEBlock(
- uint64_t block_bits, int num_bits) {
- static_assert(ValRange == 3 || ValRange == 5,
- "We only know about trits and quints");
-
- // We either have three quints or five trits
- constexpr const int kNumVals = (ValRange == 5) ? 3 : 5;
-
- // Depending on whether or not we're using quints or trits will determine
- // the positions of the interleaved bits in the encoded block.
- constexpr const int* const kInterleavedBits =
- (ValRange == 5) ? kInterleavedQuintBits : kInterleavedTritBits;
-
- // Set up the bits for reading
- base::BitStream<base::UInt128> block_bit_src(block_bits, sizeof(block_bits) * 8);
-
- // Decode the block
- std::array<int, kNumVals> m;
- uint64_t encoded = 0;
- uint32_t encoded_bits_read = 0;
- for (int i = 0; i < kNumVals; ++i) {
- {
- uint64_t bits = 0;
- const bool result = block_bit_src.GetBits(num_bits, &bits);
- assert(result);
-
- m[i] = static_cast<int>(bits);
- }
-
- uint64_t encoded_bits;
- {
- const bool result = block_bit_src.GetBits(kInterleavedBits[i], &encoded_bits);
- assert(result);
- }
- encoded |= encoded_bits << encoded_bits_read;
- encoded_bits_read += kInterleavedBits[i];
- }
-
- // Make sure that our encoded trit/quint doesn't exceed its bounds
- assert(ValRange != 3 || encoded < 256);
- assert(ValRange != 5 || encoded < 128);
-
- const int* const kEncodings = (ValRange == 5) ?
- kQuintEncodings[encoded].data() : kTritEncodings[encoded].data();
-
- std::array<int, kNumVals> result;
- for (int i = 0; i < kNumVals; ++i) {
- assert(m[i] < 1 << num_bits);
- result[i] = kEncodings[i] << num_bits | m[i];
- }
- return result;
-}
-
-// Encode a single trit or quint block using the BISE (Bounded Integer Sequence
-// Encoding) defined in Section C.2.12 of the ASTC specification. ValRange is
-// expected to be either 3 or 5 depending on whether or not we're encoding trits
-// or quints respectively. In other words, it is the remaining factor in whether
-// the passed blocks contain encoded values of the form 3*2^k or 5*2^k.
-template <int ValRange>
-void EncodeISEBlock(const std::vector<int>& vals, int bits_per_val,
- base::BitStream<base::UInt128>* bit_sink) {
- static_assert(ValRange == 3 || ValRange == 5,
- "We only know about trits and quints");
-
- // We either have three quints or five trits
- constexpr const int kNumVals = (ValRange == 5) ? 3 : 5;
-
- // Three quints in seven bits or five trits in eight bits
- constexpr const int kNumEncodedBitsPerBlock = (ValRange == 5) ? 7 : 8;
-
- // Depending on whether or not we're using quints or trits will determine
- // the positions of the interleaved bits in the encoding
- constexpr const int* const kInterleavedBits =
- (ValRange == 5) ? kInterleavedQuintBits : kInterleavedTritBits;
-
- // ISE blocks can only have up to a specific number of values...
- assert(vals.size() <= kNumVals);
-
- // Split up into bits and non bits. Non bits are used to find the quint/trit
- // encoding that we need.
- std::array<int, kNumVals> non_bits = {{ 0 }};
- std::array<int, kNumVals> bits = {{ 0 }};
- for (size_t i = 0; i < vals.size(); ++i) {
- bits[i] = vals[i] & ((1 << bits_per_val) - 1);
- non_bits[i] = vals[i] >> bits_per_val;
- assert(non_bits[i] < ValRange);
- }
-
- // We only need to add as many bits as necessary, so let's limit it based
- // on the computation described in Section C.2.22 of the ASTC specification
- const int total_num_bits =
- ((vals.size() * kNumEncodedBitsPerBlock + kNumVals - 1) / kNumVals)
- + vals.size() * bits_per_val;
- int bits_added = 0;
-
- // The number of bits used for the quint/trit encoding is necessary to know
- // in order to properly select the encoding we need to represent.
- int num_encoded_bits = 0;
- for (int i = 0; i < kNumVals; ++i) {
- bits_added += bits_per_val;
- if (bits_added >= total_num_bits) {
- break;
- }
-
- num_encoded_bits += kInterleavedBits[i];
- bits_added += kInterleavedBits[i];
- if (bits_added >= total_num_bits) {
- break;
- }
- }
- bits_added = 0;
- assert(num_encoded_bits <= kNumEncodedBitsPerBlock);
-
- // TODO(google): The faster way to do this would be to construct trees out
- // of the quint/trit encoding patterns, or just invert the decoding logic.
- // Here we go from the end backwards because it makes our tests are more
- // deterministic.
- int non_bit_encoding = -1;
- for (int j = (1 << num_encoded_bits) - 1; j >= 0; --j) {
- bool matches = true;
-
- // We don't need to match all trits here, just the ones that correspond
- // to the values that we passed in
- for (size_t i = 0; i < kNumVals; ++i) {
- if ((ValRange == 5 && kQuintEncodings[j][i] != non_bits[i]) ||
- (ValRange == 3 && kTritEncodings[j][i] != non_bits[i])) {
- matches = false;
- break;
- }
- }
-
- if (matches) {
- non_bit_encoding = j;
- break;
- }
- }
-
- assert(non_bit_encoding >= 0);
-
- // Now pack the bits into the block
- for (int i = 0; i < vals.size(); ++i) {
- // First add the base bits for this value
- if (bits_added + bits_per_val <= total_num_bits) {
- bit_sink->PutBits(bits[i], bits_per_val);
- bits_added += bits_per_val;
- }
-
- // Now add the interleaved bits from the quint/trit
- int num_int_bits = kInterleavedBits[i];
- int int_bits = non_bit_encoding & ((1 << num_int_bits) - 1);
- if (bits_added + num_int_bits <= total_num_bits) {
- bit_sink->PutBits(int_bits, num_int_bits);
- bits_added += num_int_bits;
- non_bit_encoding >>= num_int_bits;
- }
- }
-}
-
-inline void CHECK_COUNTS(int trits, int quints) {
- assert(trits == 0 || quints == 0); // Either trits or quints
- assert(trits == 0 || trits == 1); // At most one trit
- assert(quints == 0 || quints == 1); // At most one quint
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-std::array<int, kNumPossibleRanges>::const_iterator ISERangeBegin() {
- return kMaxRanges.cbegin();
-}
-
-std::array<int, kNumPossibleRanges>::const_iterator ISERangeEnd() {
- return kMaxRanges.cend();
-}
-
-void IntegerSequenceCodec::GetCountsForRange(
- int range, int* const trits, int* const quints, int* const bits) {
- // Make sure the passed pointers are valid
- assert(trits != nullptr);
- assert(quints != nullptr);
- assert(bits != nullptr);
-
- // These are generally errors -- there should never be any ASTC values
- // outside of this range
- UTILS_RELEASE_ASSERT(range > 0);
- UTILS_RELEASE_ASSERT(range < 1 << kLog2MaxRangeForBits);
-
- *bits = 0;
- *trits = 0;
- *quints = 0;
-
- // Search through the numbers of the form 2^n, 3 * 2^n and 5 * 2^n
- const int max_vals_for_range =
- *std::lower_bound(kMaxRanges.begin(), kMaxRanges.end(), range) + 1;
-
- // Make sure we found something
- assert(max_vals_for_range > 1);
-
- // Find out what kind of range it is
- if ((max_vals_for_range % 3 == 0) && IsPow2(max_vals_for_range / 3)) {
- *bits = base::Log2Floor(max_vals_for_range / 3);
- *trits = 1;
- *quints = 0;
- } else if ((max_vals_for_range % 5 == 0) && IsPow2(max_vals_for_range / 5)) {
- *bits = base::Log2Floor(max_vals_for_range / 5);
- *trits = 0;
- *quints = 1;
- } else if (IsPow2(max_vals_for_range)) {
- *bits = base::Log2Floor(max_vals_for_range);
- *trits = 0;
- *quints = 0;
- }
-
- // If we set any of these values then we're done.
- if ((*bits | *trits | *quints) != 0) {
- CHECK_COUNTS(*trits, *quints);
- }
-}
-
-// Returns the overall bit count for a range of val_count values encoded
-// using the specified number of trits, quints and straight bits (respectively)
-int IntegerSequenceCodec::GetBitCount(int num_vals,
- int trits, int quints, int bits) {
- CHECK_COUNTS(trits, quints);
-
- // See section C.2.22 for the formula used here.
- const int trit_bit_count = ((num_vals * 8 * trits) + 4) / 5;
- const int quint_bit_count = ((num_vals * 7 * quints) + 2) / 3;
- const int base_bit_count = num_vals * bits;
- return trit_bit_count + quint_bit_count + base_bit_count;
-}
-
-IntegerSequenceCodec::IntegerSequenceCodec(int range) {
- int trits, quints, bits;
- GetCountsForRange(range, &trits, &quints, &bits);
- InitializeWithCounts(trits, quints, bits);
-}
-
-IntegerSequenceCodec::IntegerSequenceCodec(
- int trits, int quints, int bits) {
- InitializeWithCounts(trits, quints, bits);
-}
-
-void IntegerSequenceCodec::InitializeWithCounts(
- int trits, int quints, int bits) {
- CHECK_COUNTS(trits, quints);
-
- if (trits > 0) {
- encoding_ = EncodingMode::kTritEncoding;
- } else if (quints > 0) {
- encoding_ = EncodingMode::kQuintEncoding;
- } else {
- encoding_ = EncodingMode::kBitEncoding;
- }
-
- bits_ = bits;
-}
-
-int IntegerSequenceCodec::NumValsPerBlock() const {
- const std::array<int, 3> kNumValsByEncoding = {{ 5, 3, 1 }};
- return kNumValsByEncoding[static_cast<int>(encoding_)];
-}
-
-int IntegerSequenceCodec::EncodedBlockSize() const {
- const std::array<int, 3> kExtraBlockSizeByEncoding = {{ 8, 7, 0 }};
- const int num_vals = NumValsPerBlock();
- return kExtraBlockSizeByEncoding[static_cast<int>(encoding_)]
- + num_vals * bits_;
-}
-
-std::vector<int> IntegerSequenceDecoder::Decode(
- int num_vals, base::BitStream<base::UInt128> *bit_src) const {
- int trits = (encoding_ == kTritEncoding)? 1 : 0;
- int quints = (encoding_ == kQuintEncoding)? 1 : 0;
- const int total_num_bits = GetBitCount(num_vals, trits, quints, bits_);
- const int bits_per_block = EncodedBlockSize();
- assert(bits_per_block < 64);
-
- int bits_left = total_num_bits;
- std::vector<int> result;
- while (bits_left > 0) {
- uint64_t block_bits;
- {
- const bool result = bit_src->GetBits(std::min(bits_left, bits_per_block), &block_bits);
- assert(result);
- }
-
- switch (encoding_) {
- case kTritEncoding: {
- auto trit_vals = DecodeISEBlock<3>(block_bits, bits_);
- result.insert(result.end(), trit_vals.begin(), trit_vals.end());
- }
- break;
-
- case kQuintEncoding: {
- auto quint_vals = DecodeISEBlock<5>(block_bits, bits_);
- result.insert(result.end(), quint_vals.begin(), quint_vals.end());
- }
- break;
-
- case kBitEncoding:
- result.push_back(static_cast<int>(block_bits));
- break;
- }
-
- bits_left -= bits_per_block;
- }
-
- // Resize result to only contain as many values as requested
- assert(result.size() >= static_cast<size_t>(num_vals));
- result.resize(num_vals);
-
- // Encoded all the values
- return result;
-}
-
-void IntegerSequenceEncoder::Encode(base::BitStream<base::UInt128>* bit_sink) const {
- // Go through all of the values and chop them up into blocks. The properties
- // of the trit and quint encodings mean that if we need to encode fewer values
- // in a block than the number of values encoded in the block then we need to
- // consider the last few values to be zero.
-
- auto next_val = vals_.begin();
- while (next_val != vals_.end()) {
- switch (encoding_) {
- case kTritEncoding: {
- std::vector<int> trit_vals;
- for (int i = 0; i < 5; ++i) {
- if (next_val != vals_.end()) {
- trit_vals.push_back(*next_val);
- ++next_val;
- }
- }
-
- EncodeISEBlock<3>(trit_vals, bits_, bit_sink);
- }
- break;
-
- case kQuintEncoding: {
- std::vector<int> quint_vals;
- for (int i = 0; i < 3; ++i) {
- if (next_val != vals_.end()) {
- quint_vals.push_back(*next_val);
- ++next_val;
- }
- }
-
- EncodeISEBlock<5>(quint_vals, bits_, bit_sink);
- }
- break;
-
- case kBitEncoding: {
- bit_sink->PutBits(*next_val, EncodedBlockSize());
- ++next_val;
- }
- break;
- }
- }
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/integer_sequence_codec.h b/third-party/astc-codec/src/decoder/integer_sequence_codec.h
deleted file mode 100644
index a815e096..00000000
--- a/third-party/astc-codec/src/decoder/integer_sequence_codec.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_INTEGER_SEQUENCE_CODEC_H_
-#define ASTC_CODEC_DECODER_INTEGER_SEQUENCE_CODEC_H_
-
-#include "src/base/bit_stream.h"
-#include "src/base/uint128.h"
-
-#include <array>
-#include <string>
-#include <vector>
-
-namespace astc_codec {
-
-// The maximum number of bits that we would need to encode an ISE value. The
-// ASTC specification does not give a maximum number, however unquantized color
-// values have a maximum range of 255, meaning that we can't feasibly have more
-// than eight bits per value.
-constexpr int kLog2MaxRangeForBits = 8;
-
-// Ranges can take any of the the forms 2^k, 3*2^k, or 5*2^k for k up to
-// kLog2MaxRangeForBits. Hence we have three types of ranges. Since the
-// maximum encoded value is 255, k won't go larger than 8. We don't have quints
-// that accompany [6, 8]-bits, as (5 * 2^6 = 320 > 255) and we don't have trits
-// that accompany [7, 8]-bits, as (3 * 2^7 = 384 > 255). But we do have trits
-// and quints that accompany no bits. Hence we have a total of
-// 3 * kLog2MaxRangeForBits - 3 - 2 + 2 total ranges.
-constexpr int kNumPossibleRanges = 3 * kLog2MaxRangeForBits - 3;
-
-// Returns an iterator through the available ASTC ranges.
-std::array<int, kNumPossibleRanges>::const_iterator ISERangeBegin();
-std::array<int, kNumPossibleRanges>::const_iterator ISERangeEnd();
-
-// Base class for ASTC integer sequence encoders and decoders. These codecs
-// operate on sequences of integers and produce bit patterns that pack the
-// integers based on the encoding scheme specified in the ASTC specification
-// Section C.2.12. The resulting bit pattern is a sequence of encoded blocks.
-// All blocks in a sequence are one of the following encodings:
-//
-// (1 -- bit encoding) one encoded value of the form 2^k
-// (2 -- trit encoding) five encoded values of the form 3*2^k
-// (3 -- quint encoding) three encoded values of the form 5*2^k
-//
-// The layouts of each block are designed such that the blocks can be truncated
-// during encoding in order to support variable length input sequences (i.e. a
-// sequence of values that are encoded using trit encoded blocks does not
-// need to have a multiple-of-five length).
-class IntegerSequenceCodec {
- public:
- // Returns the number of trits, quints, and bits needed to encode values in
- // [0, range]. This is used to determine the layout of ISE encoded bit
- // streams. The returned array holds the number of trits, quints, and bits
- // respectively. range is expected to be within the interval [1, 5242879]
- static void GetCountsForRange(int range, int* trits, int* quints, int* bits);
-
- // Returns the number of bits needed to encode the given number of values with
- // respect to the number of trits, quints, and bits specified in ise_counts
- // (in that order). It is expected that either trits or quints can be
- // nonzero, but not both, and neither can be larger than one. Anything else is
- // undefined.
- static int GetBitCount(int num_vals, int trits, int quints, int bits);
-
- // Convenience function that returns the number of bits needed to encoded
- // num_vals within the range [0, range] (inclusive).
- static inline int GetBitCountForRange(int num_vals, int range) {
- int trits, quints, bits;
- GetCountsForRange(range, &trits, &quints, &bits);
- return GetBitCount(num_vals, trits, quints, bits);
- }
-
- protected:
- explicit IntegerSequenceCodec(int range);
- IntegerSequenceCodec(int trits, int quints, int bits);
-
- // The encoding mode -- since having trits and quints are mutually exclusive,
- // we can store the encoding we decide on in this enum.
- enum EncodingMode {
- kTritEncoding = 0,
- kQuintEncoding,
- kBitEncoding,
- };
-
- EncodingMode encoding_;
- int bits_;
-
- // Returns the number of values stored in a single ISE block. Since quints and
- // trits are packed three/five to a bit pattern (respectively), each sequence
- // is chunked into blocks in order to encode it. For only bit-encodings, the
- // block size is one.
- int NumValsPerBlock() const;
-
- // Returns the size of a single ISE block in bits (see NumValsPerBlock).
- int EncodedBlockSize() const;
-
- private:
- // Determines the encoding mode.
- void InitializeWithCounts(int trits, int quints, int bits);
-};
-
-// The integer sequence decoder. The decoder only remembers the given encoding
-// but each invocation of Decode operates independently on the input bits.
-class IntegerSequenceDecoder : public IntegerSequenceCodec {
- public:
- // Creates a decoder that decodes values within [0, range] (inclusive).
- explicit IntegerSequenceDecoder(int range)
- : IntegerSequenceCodec(range) { }
-
- // Creates a decoder based on the number of trits, quints, and bits expected
- // in the bit stream passed to Decode.
- IntegerSequenceDecoder(int trits, int quints, int bits)
- : IntegerSequenceCodec(trits, quints, bits) { }
-
- // Decodes num_vals from the bit_src. The number of bits read is dependent
- // on the number of bits required to encode num_vals based on the calculation
- // provided in Section C.2.22 of the ASTC specification. The return value
- // always contains exactly num_vals.
- std::vector<int> Decode(int num_vals,
- base::BitStream<base::UInt128>* bit_src) const;
-};
-
-// The integer sequence encoder. The encoder accepts values one by one and
-// places them into a temporary array that it holds. When needed the user
-// may call Encode to produce an encoded bit stream of the associated values.
-class IntegerSequenceEncoder : public IntegerSequenceCodec {
- public:
- // Creates an encoder that encodes values within [0, range] (inclusive).
- explicit IntegerSequenceEncoder(int range)
- : IntegerSequenceCodec(range) { }
-
- // Creates an encoder based on the number of trits, quints, and bits for
- // the bit stream produced by Encode.
- IntegerSequenceEncoder(int trits, int quints, int bits)
- : IntegerSequenceCodec(trits, quints, bits) { }
-
- // Adds a value to the encoding sequence.
- void AddValue(int val) {
- // Make sure it's within bounds
- assert(encoding_ != EncodingMode::kTritEncoding || val < 3 * (1 << bits_));
- assert(encoding_ != EncodingMode::kQuintEncoding || val < 5 * (1 << bits_));
- assert(encoding_ != EncodingMode::kBitEncoding || val < (1 << bits_));
- vals_.push_back(val);
- }
-
- // Writes the encoding for vals_ to the bit_sink. Multiple calls to Encode
- // will produce the same result.
- void Encode(base::BitStream<base::UInt128>* bit_sink) const;
-
- // Removes all of the previously added values to the encoder.
- void Reset() { vals_.clear(); }
-
- private:
- std::vector<int> vals_;
-};
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_INTEGER_SEQUENCE_CODEC_H_
diff --git a/third-party/astc-codec/src/decoder/intermediate_astc_block.cc b/third-party/astc-codec/src/decoder/intermediate_astc_block.cc
deleted file mode 100644
index e03af1eb..00000000
--- a/third-party/astc-codec/src/decoder/intermediate_astc_block.cc
+++ /dev/null
@@ -1,591 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/intermediate_astc_block.h"
-#include "src/decoder/integer_sequence_codec.h"
-#include "src/base/bit_stream.h"
-#include "src/base/math_utils.h"
-#include "src/base/optional.h"
-#include "src/base/uint128.h"
-
-#include <algorithm>
-#include <numeric>
-#include <sstream>
-
-namespace astc_codec {
-
-namespace {
-
-constexpr int kEndpointRange_ReturnInvalidWeightDims = -1;
-constexpr int kEndpointRange_ReturnNotEnoughColorBits = -2;
-
-base::UInt128 PackVoidExtentBlock(uint16_t r, uint16_t g, uint16_t b,
- uint16_t a, std::array<uint16_t, 4> coords) {
- base::BitStream<base::UInt128> bit_sink;
-
- // Put void extent mode...
- bit_sink.PutBits(0xDFC, 12);
-
- // Each of the coordinates goes in 13 bits at a time.
- for (auto coord : coords) {
- assert(coord < 1 << 13);
- bit_sink.PutBits(coord, 13);
- }
- assert(bit_sink.Bits() == 64);
-
- // Then we add R, G, B, and A in order
- bit_sink.PutBits(r, 16);
- bit_sink.PutBits(g, 16);
- bit_sink.PutBits(b, 16);
- bit_sink.PutBits(a, 16);
-
- assert(bit_sink.Bits() == 128);
-
- base::UInt128 result;
- bit_sink.GetBits(128, &result);
- return result;
-}
-
-base::Optional<std::string> GetEncodedWeightRange(int range,
- std::array<int, 3>* const r) {
- const std::array<std::array<int, 3>, 12> kValidRangeEncodings =
- {{ {{ 0, 1, 0 }}, {{ 1, 1, 0 }}, {{ 0, 0, 1 }},
- {{ 1, 0, 1 }}, {{ 0, 1, 1 }}, {{ 1, 1, 1 }},
- {{ 0, 1, 0 }}, {{ 1, 1, 0 }}, {{ 0, 0, 1 }},
- {{ 1, 0, 1 }}, {{ 0, 1, 1 }}, {{ 1, 1, 1 }} }};
-
- // If our range is larger than all available ranges, this is an error.
- const int smallest_range = kValidWeightRanges.front();
- const int largest_range = kValidWeightRanges.back();
- if (range < smallest_range || largest_range < range) {
- std::stringstream strm;
- strm << "Could not find block mode. Invalid weight range: "
- << range << " not in [" << smallest_range << ", "
- << largest_range << std::endl;
- return strm.str();
- }
-
- // Find the upper bound on the range, otherwise.
- const auto range_iter = std::lower_bound(
- kValidWeightRanges.cbegin(), kValidWeightRanges.cend(), range);
- auto enc_iter = kValidRangeEncodings.cbegin();
- enc_iter += std::distance(kValidWeightRanges.cbegin(), range_iter);
- *r = *enc_iter;
- return {};
-}
-
-struct BlockModeInfo {
- int min_weight_grid_dim_x;
- int max_weight_grid_dim_x;
- int min_weight_grid_dim_y;
- int max_weight_grid_dim_y;
- int r0_bit_pos;
- int r1_bit_pos;
- int r2_bit_pos;
- int weight_grid_x_offset_bit_pos;
- int weight_grid_y_offset_bit_pos;
- bool require_single_plane_low_prec;
-};
-
-constexpr int kNumBlockModes = 10;
-const std::array<BlockModeInfo, kNumBlockModes> kBlockModeInfo {{
- { 4, 7, 2, 5, 4, 0, 1, 7, 5, false }, // B+4 A+2
- { 8, 11, 2, 5, 4, 0, 1, 7, 5, false }, // B+8 A+2
- { 2, 5, 8, 11, 4, 0, 1, 5, 7, false }, // A+2 B+8
- { 2, 5, 6, 7, 4, 0, 1, 5, 7, false }, // A+2 B+6
- { 2, 3, 2, 5, 4, 0, 1, 7, 5, false }, // B+2 A+2
- { 12, 12, 2, 5, 4, 2, 3, -1, 5, false }, // 12 A+2
- { 2, 5, 12, 12, 4, 2, 3, 5, -1, false }, // A+2 12
- { 6, 6, 10, 10, 4, 2, 3, -1, -1, false }, // 6 10
- { 10, 10, 6, 6, 4, 2, 3, -1, -1, false }, // 10 6
- { 6, 9, 6, 9, 4, 2, 3, 5, 9, true } // A+6 B+6
-}};
-
-// These are the bits that must be set for ASTC to recognize a given
-// block mode. They are the 1's set in table C.2.8 of the spec.
-const std::array<int, kNumBlockModes> kBlockModeMask = {{
- 0x0, 0x4, 0x8, 0xC, 0x10C, 0x0, 0x80, 0x180, 0x1A0, 0x100
-}};
-
-static base::Optional<std::string> PackBlockMode(int dim_x, int dim_y, int range,
- bool dual_plane,
- base::BitStream<base::UInt128>* const bit_sink) {
- // We need to set the high precision bit if our range is too high...
- bool high_prec = range > 7;
-
- std::array<int, 3> r;
- const auto result = GetEncodedWeightRange(range, &r);
- if (result) {
- return result;
- }
-
- // The high two bits of R must not be zero. If this happens then it's
- // an illegal encoding according to Table C.2.7 that should have gotten
- // caught in GetEncodedWeightRange
- assert((r[1] | r[2]) > 0);
-
- // Just go through the table and see if any of the modes can handle
- // the given dimensions.
- for (int mode = 0; mode < kNumBlockModes; ++mode) {
- const BlockModeInfo& block_mode = kBlockModeInfo[mode];
-
- bool is_valid_mode = true;
- is_valid_mode &= block_mode.min_weight_grid_dim_x <= dim_x;
- is_valid_mode &= dim_x <= block_mode.max_weight_grid_dim_x;
- is_valid_mode &= block_mode.min_weight_grid_dim_y <= dim_y;
- is_valid_mode &= dim_y <= block_mode.max_weight_grid_dim_y;
- is_valid_mode &= !(block_mode.require_single_plane_low_prec && dual_plane);
- is_valid_mode &= !(block_mode.require_single_plane_low_prec && high_prec);
-
- if (!is_valid_mode) {
- continue;
- }
-
- // Initialize to the bits we must set.
- uint32_t encoded_mode = kBlockModeMask[mode];
- auto setBit = [&encoded_mode](const uint32_t value, const uint32_t offset) {
- encoded_mode = (encoded_mode & ~(1 << offset)) | ((value & 1) << offset);
- };
-
- // Set all the bits we need to set
- setBit(r[0], block_mode.r0_bit_pos);
- setBit(r[1], block_mode.r1_bit_pos);
- setBit(r[2], block_mode.r2_bit_pos);
-
- // Find our width and height offset from the base width and height weight
- // grid dimension for the given block mode. These are the 1-2 bits that
- // get encoded in the block mode used to calculate the final weight grid
- // width and height.
- const int offset_x = dim_x - block_mode.min_weight_grid_dim_x;
- const int offset_y = dim_y - block_mode.min_weight_grid_dim_y;
-
- // If we don't have an offset position then our offset better be zero.
- // If this isn't the case, then this isn't a viable block mode and we
- // should have caught this sooner.
- assert(block_mode.weight_grid_x_offset_bit_pos >= 0 || offset_x == 0);
- assert(block_mode.weight_grid_y_offset_bit_pos >= 0 || offset_y == 0);
-
- encoded_mode |= offset_x << block_mode.weight_grid_x_offset_bit_pos;
- encoded_mode |= offset_y << block_mode.weight_grid_y_offset_bit_pos;
-
- if (!block_mode.require_single_plane_low_prec) {
- setBit(high_prec, 9);
- setBit(dual_plane, 10);
- }
-
- // Make sure that the mode is the first thing the bit sink is writing to
- assert(bit_sink->Bits() == 0);
- bit_sink->PutBits(encoded_mode, 11);
-
- return {};
- }
-
- return std::string("Could not find viable block mode");
-}
-
-// Returns true if all endpoint modes are equal.
-bool SharedEndpointModes(const IntermediateBlockData& data) {
- return std::accumulate(
- data.endpoints.begin(), data.endpoints.end(), true,
- [&data](const bool& a, const IntermediateEndpointData& b) {
- return a && b.mode == data.endpoints[0].mode;
- });
-}
-
-// Returns the starting bit (between 0 and 128) where the extra CEM and
-// dual plane info is stored in the ASTC block.
-int ExtraConfigBitPosition(const IntermediateBlockData& data) {
- const bool has_dual_channel = data.dual_plane_channel.hasValue();
- const int num_weights = data.weight_grid_dim_x * data.weight_grid_dim_y *
- (has_dual_channel ? 2 : 1);
- const int num_weight_bits =
- IntegerSequenceCodec::GetBitCountForRange(num_weights, data.weight_range);
-
- int extra_config_bits = 0;
- if (!SharedEndpointModes(data)) {
- const int num_encoded_cem_bits = 2 + data.endpoints.size() * 3;
- extra_config_bits = num_encoded_cem_bits - 6;
- }
-
- if (has_dual_channel) {
- extra_config_bits += 2;
- }
-
- return 128 - num_weight_bits - extra_config_bits;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-base::Optional<IntermediateBlockData> UnpackIntermediateBlock(
- const PhysicalASTCBlock& pb) {
- if (pb.IsIllegalEncoding()) {
- return {};
- }
-
- if (pb.IsVoidExtent()) {
- return {};
- }
-
- // Non void extent? Then let's try to decode everything else.
- IntermediateBlockData data;
-
- // All blocks have color values...
- const base::UInt128 color_bits_mask =
- (base::UInt128(1) << pb.NumColorBits().value()) - 1;
- const base::UInt128 color_bits =
- (pb.GetBlockBits() >> pb.ColorStartBit().value()) & color_bits_mask;
- base::BitStream<base::UInt128> bit_src(color_bits, 128);
-
- IntegerSequenceDecoder color_decoder(pb.ColorValuesRange().value());
- const int num_colors_in_block = pb.NumColorValues().value();
- std::vector<int> colors = color_decoder.Decode(num_colors_in_block, &bit_src);
-
- // Decode simple info
- const auto weight_dims = pb.WeightGridDims();
- data.weight_grid_dim_x = weight_dims->at(0);
- data.weight_grid_dim_y = weight_dims->at(1);
- data.weight_range = pb.WeightRange().value();
-
- data.partition_id = pb.PartitionID();
- data.dual_plane_channel = pb.DualPlaneChannel();
-
- auto colors_iter = colors.begin();
- for (int i = 0; i < pb.NumPartitions().value(); ++i) {
- IntermediateEndpointData ep_data;
- ep_data.mode = pb.GetEndpointMode(i).value();
-
- const int num_colors = NumColorValuesForEndpointMode(ep_data.mode);
- ep_data.colors.insert(ep_data.colors.end(), colors_iter,
- colors_iter + num_colors);
- colors_iter += num_colors;
-
- data.endpoints.push_back(ep_data);
- }
- assert(colors_iter == colors.end());
- data.endpoint_range = pb.ColorValuesRange().value();
-
- // Finally decode the weights
- const base::UInt128 weight_bits_mask =
- (base::UInt128(1) << pb.NumWeightBits().value()) - 1;
- const base::UInt128 weight_bits =
- base::ReverseBits(pb.GetBlockBits()) & weight_bits_mask;
- bit_src = base::BitStream<base::UInt128>(weight_bits, 128);
-
- IntegerSequenceDecoder weight_decoder(data.weight_range);
- int num_weights = data.weight_grid_dim_x * data.weight_grid_dim_y;
- num_weights *= pb.IsDualPlane() ? 2 : 1;
- data.weights = weight_decoder.Decode(num_weights, &bit_src);
-
- return data;
-}
-
-int EndpointRangeForBlock(const IntermediateBlockData& data) {
- // First check to see if we exceed the number of bits allotted for weights, as
- // specified in C.2.24. If so, then the endpoint range is meaningless, but not
- // because we had an overzealous color endpoint mode, so return a different
- // error code.
- if (IntegerSequenceCodec::GetBitCountForRange(
- data.weight_grid_dim_x * data.weight_grid_dim_y *
- (data.dual_plane_channel.hasValue() ? 2 : 1),
- data.weight_range) > 96) {
- return kEndpointRange_ReturnInvalidWeightDims;
- }
-
- const int num_partitions = data.endpoints.size();
-
- // Calculate the number of bits that we would write prior to getting to the
- // color endpoint data
- const int bits_written =
- 11 // Block mode
- + 2 // Num partitions
- + ((num_partitions > 1) ? 10 : 0) // Partition ID
- + ((num_partitions == 1) ? 4 : 6); // Shared CEM bits
-
- // We can determine the range based on how many bits we have between the start
- // of the color endpoint data and the next section, which is the extra config
- // bit position
- const int color_bits_available = ExtraConfigBitPosition(data) - bits_written;
-
- int num_color_values = 0;
- for (const auto& ep_data : data.endpoints) {
- num_color_values += NumColorValuesForEndpointMode(ep_data.mode);
- }
-
- // There's no way any valid ASTC encoding has no room left for any color
- // values. If we hit this then something is wrong in the caller -- abort.
- // According to section C.2.24, the smallest number of bits available is
- // ceil(13*C/5), where C is the number of color endpoint integers needed.
- const int bits_needed = (13 * num_color_values + 4) / 5;
- if (color_bits_available < bits_needed) {
- return kEndpointRange_ReturnNotEnoughColorBits;
- }
-
- int color_value_range = 255;
- for (; color_value_range > 1; --color_value_range) {
- const int bits_for_range = IntegerSequenceCodec::GetBitCountForRange(
- num_color_values, color_value_range);
- if (bits_for_range <= color_bits_available) {
- break;
- }
- }
-
- return color_value_range;
-}
-
-base::Optional<VoidExtentData> UnpackVoidExtent(const PhysicalASTCBlock& pb) {
- if (pb.IsIllegalEncoding()) {
- return {};
- }
-
- if (!pb.IsVoidExtent()) {
- return {};
- }
-
- // All blocks have color values...
- const base::UInt128 color_bits_mask =
- (base::UInt128(1) << pb.NumColorBits().value()) - 1;
- const uint64_t color_bits = (
- (pb.GetBlockBits() >> pb.ColorStartBit().value()) & color_bits_mask).LowBits();
-
- assert(pb.NumColorValues().value() == 4);
- VoidExtentData data;
- data.r = static_cast<uint16_t>((color_bits >> 0) & 0xFFFF);
- data.g = static_cast<uint16_t>((color_bits >> 16) & 0xFFFF);
- data.b = static_cast<uint16_t>((color_bits >> 32) & 0xFFFF);
- data.a = static_cast<uint16_t>((color_bits >> 48) & 0xFFFF);
-
- const auto void_extent_coords = pb.VoidExtentCoords();
- if (void_extent_coords) {
- data.coords[0] = void_extent_coords->at(0);
- data.coords[1] = void_extent_coords->at(1);
- data.coords[2] = void_extent_coords->at(2);
- data.coords[3] = void_extent_coords->at(3);
- } else {
- uint16_t all_ones = (1 << 13) - 1;
- for (auto& coord : data.coords) {
- coord = all_ones;
- }
- }
-
- return data;
-}
-
-// Packs the given intermediate block into a physical block. Returns false if
-// the provided values in the intermediate block emit an illegal ASTC
-// encoding.
-base::Optional<std::string> Pack(const IntermediateBlockData& data,
- base::UInt128* pb) {
- if (data.weights.size() !=
- data.weight_grid_dim_x * data.weight_grid_dim_y *
- (data.dual_plane_channel.hasValue() ? 2 : 1)) {
- return std::string("Incorrect number of weights!");
- }
-
- // If it's not a void extent block, then it gets a bit more tricky...
- base::BitStream<base::UInt128> bit_sink;
-
- // First we need to encode the block mode.
- const auto error_string = PackBlockMode(
- data.weight_grid_dim_x, data.weight_grid_dim_y, data.weight_range,
- data.dual_plane_channel.hasValue(), &bit_sink);
- if (error_string) {
- return error_string;
- }
-
- // Next, we place the number of partitions minus one.
- const int num_partitions = data.endpoints.size();
- bit_sink.PutBits(num_partitions - 1, 2);
-
- // If we have more than one partition, then we also have a partition ID.
- if (num_partitions > 1) {
- const int id = data.partition_id.value();
- assert(id >= 0);
- bit_sink.PutBits(id, 10);
- }
-
- // Take a detour, let's encode the weights so that we know how many bits they
- // consume.
- base::BitStream<base::UInt128> weight_sink;
-
- IntegerSequenceEncoder weight_enc(data.weight_range);
- for (auto weight : data.weights) {
- weight_enc.AddValue(weight);
- }
- weight_enc.Encode(&weight_sink);
-
- const int num_weight_bits = weight_sink.Bits();
- assert(num_weight_bits ==
- IntegerSequenceCodec::GetBitCountForRange(
- data.weights.size(), data.weight_range));
-
- // Let's continue... how much after the color data do we need to write?
- int extra_config = 0;
-
- // Determine if all endpoint pairs share the same endpoint mode
- assert(data.endpoints.size() > 0);
- bool shared_endpoint_mode = SharedEndpointModes(data);
-
- // The first part of the endpoint mode (CEM) comes directly after the
- // partition info, if it exists. If there is no partition info, the CEM comes
- // right after the block mode. In the single-partition case, we just write out
- // the entire singular CEM, but in the multi-partition case, if all CEMs are
- // the same then their shared CEM is specified directly here, too. In both
- // cases, shared_endpoint_mode is true (in the singular case,
- // shared_endpoint_mode is trivially true).
- if (shared_endpoint_mode) {
- if (num_partitions > 1) {
- bit_sink.PutBits(0, 2);
- }
- bit_sink.PutBits(static_cast<int>(data.endpoints[0].mode), 4);
- } else {
- // Here, the CEM is not shared across all endpoint pairs, and we need to
- // figure out what to place here, and what to place in the extra config
- // bits before the weight data...
-
- // Non-shared config modes must all be within the same class (out of four)
- // See Section C.2.11
- int min_class = 2; // We start with 2 here instead of three because it's
- // the highest that can be encoded -- even if all modes
- // are class 3.
- int max_class = 0;
- for (const auto& ep_data : data.endpoints) {
- const int ep_mode_class = static_cast<int>(ep_data.mode) >> 2;
- min_class = std::min(min_class, ep_mode_class);
- max_class = std::max(max_class, ep_mode_class);
- }
-
- assert(max_class >= min_class);
-
- if (max_class - min_class > 1) {
- return std::string("Endpoint modes are invalid");
- }
-
- // Construct the CEM mode -- six of its bits will fit here, but otherwise
- // the rest will go in the extra configuration bits.
- base::BitStream<uint32_t> cem_encoder;
-
- // First encode the base class
- assert(min_class >= 0);
- assert(min_class < 3);
- cem_encoder.PutBits(min_class + 1, 2);
-
- // Next, encode the class selector bits -- this is simply the offset
- // from the base class
- for (const auto& ep_data : data.endpoints) {
- const int ep_mode_class = static_cast<int>(ep_data.mode) >> 2;
- const int class_selector_bit = ep_mode_class - min_class;
- assert(class_selector_bit == 0 || class_selector_bit == 1);
- cem_encoder.PutBits(class_selector_bit, 1);
- }
-
- // Finally, we need to choose from each class which actual mode
- // we belong to and encode those.
- for (const auto& ep_data : data.endpoints) {
- const int ep_mode = static_cast<int>(ep_data.mode) & 3;
- assert(ep_mode < 4);
- cem_encoder.PutBits(ep_mode, 2);
- }
- assert(cem_encoder.Bits() == 2 + num_partitions * 3);
-
- uint32_t encoded_cem;
- cem_encoder.GetBits(2 + num_partitions * 3, &encoded_cem);
-
- // Since only six bits fit here before the color endpoint data, the rest
- // need to go in the extra config data.
- extra_config = encoded_cem >> 6;
-
- // Write out the six bits we had
- bit_sink.PutBits(encoded_cem, 6);
- }
-
- // If we have a dual-plane channel, we can tack that onto our extra config
- // data
- if (data.dual_plane_channel.hasValue()) {
- const int channel = data.dual_plane_channel.value();
- assert(channel < 4);
- extra_config <<= 2;
- extra_config |= channel;
- }
-
- // Get the range of endpoint values. It can't be -1 because we should have
- // checked for that much earlier.
- const int color_value_range = data.endpoint_range
- ? data.endpoint_range.value()
- : EndpointRangeForBlock(data);
-
- assert(color_value_range != kEndpointRange_ReturnInvalidWeightDims);
- if (color_value_range == kEndpointRange_ReturnNotEnoughColorBits) {
- return { "Intermediate block emits illegal color range" };
- }
-
- IntegerSequenceEncoder color_enc(color_value_range);
- for (const auto& ep_data : data.endpoints) {
- for (int color : ep_data.colors) {
- if (color > color_value_range) {
- return { "Color outside available color range!" };
- }
-
- color_enc.AddValue(color);
- }
- }
- color_enc.Encode(&bit_sink);
-
- // Now we need to skip some bits to get to the extra configuration bits. The
- // number of bits we need to skip depends on where we are in the stream and
- // where we need to get to.
- const int extra_config_bit_position = ExtraConfigBitPosition(data);
- const int extra_config_bits =
- 128 - num_weight_bits - extra_config_bit_position;
- assert(extra_config_bits >= 0);
- assert(extra_config < 1 << extra_config_bits);
-
- // Make sure the color encoder didn't write more than we thought it would.
- int bits_to_skip = extra_config_bit_position - bit_sink.Bits();
- assert(bits_to_skip >= 0);
-
- while (bits_to_skip > 0) {
- const int skipping = std::min(32, bits_to_skip);
- bit_sink.PutBits(0, skipping);
- bits_to_skip -= skipping;
- }
-
- // Finally, write out the rest of the config bits.
- bit_sink.PutBits(extra_config, extra_config_bits);
-
- // We should be right up to the weight bits...
- assert(bit_sink.Bits() == 128 - num_weight_bits);
-
- // Flush out our bit writer and write out the weight bits
- base::UInt128 astc_bits;
- bit_sink.GetBits(128 - num_weight_bits, &astc_bits);
-
- base::UInt128 rev_weight_bits;
- weight_sink.GetBits(weight_sink.Bits(), &rev_weight_bits);
-
- astc_bits |= base::ReverseBits(rev_weight_bits);
-
- // And we're done! Whew!
- *pb = astc_bits;
- return PhysicalASTCBlock(*pb).IsIllegalEncoding();
-}
-
-base::Optional<std::string> Pack(const VoidExtentData& data,
- base::UInt128* pb) {
- *pb = PackVoidExtentBlock(data.r, data.g, data.b, data.a, data.coords);
- return PhysicalASTCBlock(*pb).IsIllegalEncoding();
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/intermediate_astc_block.h b/third-party/astc-codec/src/decoder/intermediate_astc_block.h
deleted file mode 100644
index ec6eb3ea..00000000
--- a/third-party/astc-codec/src/decoder/intermediate_astc_block.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_INTERMEDIATE_ASTC_BLOCK_H_
-#define ASTC_CODEC_DECODER_INTERMEDIATE_ASTC_BLOCK_H_
-
-#include "src/base/optional.h"
-#include "src/base/uint128.h"
-#include "src/decoder/physical_astc_block.h"
-
-#include <array>
-#include <vector>
-
-namespace astc_codec {
-
-// From Table C.2.7 -- These are the only valid ranges that weight
-// values can take.
-constexpr std::array<int, 12> kValidWeightRanges =
-{{ 1, 2, 3, 4, 5, 7, 9, 11, 15, 19, 23, 31 }};
-
-// Void extent data are all the ASTC blocks that are labeled for having a
-// constant color. In the ASTC spec, some of these blocks may optionally
-// have "void extent coordinates" that describe how far in texture space
-// the constant color should span. If these coordinates are not valid,
-// then the coordinates are all set to a fully saturated bit mask
-// ((1 << 13) - 1) and the block is treated as a singular constant color.
-// We call both types of these blocks "void extent" to remove confusion
-// in our code.
-struct VoidExtentData {
- uint16_t r;
- uint16_t g;
- uint16_t b;
- uint16_t a;
- std::array<uint16_t, 4> coords;
-};
-
-// Intermediate endpoint data. Really this is just an endpoint mode
-// and a couple of values that represent the data used to decode the
-// RGB values from the color endpoint mode.
-struct IntermediateEndpointData {
- ColorEndpointMode mode;
- std::vector<int> colors;
-};
-
-// This is an unpacked physical ASTC block, but it does not have enough
-// information to be worked with logically. It is simply a container of
-// all of the unpacked ASTC information. It is used as a staging area
-// for the information that is later Pack()'d into a PhysicalASTCBlock.
-struct IntermediateBlockData {
- int weight_grid_dim_x;
- int weight_grid_dim_y;
- int weight_range;
-
- // Quantized, non-interpolated weights
- std::vector<int> weights;
-
- // The 10-bit partition ID if we need one
- base::Optional<int> partition_id;
-
- // The dual-plane channel in [0, 3] if it exists.
- base::Optional<int> dual_plane_channel;
-
- // The quantized/encoded endpoint values for this block. The range of each
- // endpoint value is specified by |endpoint_range|, if it exists. If not, the
- // range can be queried by calling EndpointRangeForBlock
- std::vector<IntermediateEndpointData> endpoints;
-
- // The range [0, endpoint_range] that any one endpoint value can take. Users
- // should not write to this value themselves. If it is empty at the time
- // someone calls Pack(), it will be automatically inferred. Otherwise, it is
- // set by Unpack() based on what the underlying encoding specified.
- base::Optional<int> endpoint_range;
-};
-
-// Returns the maximum value that a given endpoint value can take according to
-// the other settings in the block. Ignores the |endpoint_range| member
-// variable. Returns negative values on error:
-// -1 : Too many bits required to store weight grid
-// -2 : There are too few bits allocated for color endpoint data according to
-// C.2.24 in the ASTC spec
-int EndpointRangeForBlock(const IntermediateBlockData& data);
-inline int EndpointRangeForBlock(const VoidExtentData& data);
-
-// Unpacks the physical ASTC block into the intermediate block. Returns false
-// if the physical block is an error encoded block, or if the physical block
-// is a void extent block. On error the contents of ib are undefined.
-base::Optional<IntermediateBlockData> UnpackIntermediateBlock(
- const PhysicalASTCBlock& pb);
-
-// Unpacks the physical ASTC block into a void extent block. Returns false
-// if the physical block is an error encoded block, or if the physical block
-// is an intermediate block. On error the contents of ib are undefined.
-base::Optional<VoidExtentData> UnpackVoidExtent(const PhysicalASTCBlock& pb);
-
-// Packs the given intermediate block into a physical block. Returns an error
-// string if the provided values in the intermediate block emit an illegal ASTC
-// encoding. In this case the results in the physical block are undefined.
-base::Optional<std::string> Pack(const IntermediateBlockData& data,
- base::UInt128* pb);
-
-// Packs the given void extent block into a physical block. Returns an error
-// string if the provided values in the void extent block emit an illegal ASTC
-// encoding. In this case the results in the physical block are undefined.
-base::Optional<std::string> Pack(const VoidExtentData& data, base::UInt128* pb);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Impl
-
-inline int EndpointRangeForBlock(const VoidExtentData& data) {
- // Void extent blocks use 16-bit ARGB definitions
- return (1 << 16) - 1;
-}
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_INTERMEDIATE_ASTC_BLOCK_H_
diff --git a/third-party/astc-codec/src/decoder/logical_astc_block.cc b/third-party/astc-codec/src/decoder/logical_astc_block.cc
deleted file mode 100644
index 9271e181..00000000
--- a/third-party/astc-codec/src/decoder/logical_astc_block.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/logical_astc_block.h"
-#include "src/decoder/endpoint_codec.h"
-#include "src/decoder/footprint.h"
-#include "src/decoder/integer_sequence_codec.h"
-#include "src/decoder/quantization.h"
-#include "src/decoder/weight_infill.h"
-
-namespace astc_codec {
-
-namespace {
-
-Partition GenerateSinglePartition(Footprint footprint) {
- return Partition { footprint, /* num_parts = */ 1, /* partition_id = */ 0,
- std::vector<int>(footprint.NumPixels(), 0) };
-}
-
-static std::vector<EndpointPair> DecodeEndpoints(const IntermediateBlockData& block) {
- const int endpoint_range = block.endpoint_range
- ? block.endpoint_range.value()
- : EndpointRangeForBlock(block);
- assert(endpoint_range > 0);
-
- std::vector<EndpointPair> endpoints;
- for (const auto& eps : block.endpoints) {
- RgbaColor decmp_one_rgba, decmp_two_rgba;
- DecodeColorsForMode(eps.colors, endpoint_range, eps.mode,
- &decmp_one_rgba, &decmp_two_rgba);
- endpoints.emplace_back(decmp_one_rgba, decmp_two_rgba);
- }
- return endpoints;
-}
-
-static std::vector<EndpointPair> DecodeEndpoints(const VoidExtentData& block) {
- EndpointPair eps;
- eps.first[0] = eps.second[0] = (block.r * 255) / 65535;
- eps.first[1] = eps.second[1] = (block.g * 255) / 65535;
- eps.first[2] = eps.second[2] = (block.b * 255) / 65535;
- eps.first[3] = eps.second[3] = (block.a * 255) / 65535;
-
- std::vector<EndpointPair> endpoints;
- endpoints.emplace_back(eps);
- return endpoints;
-}
-
-Partition ComputePartition(const Footprint& footprint,
- const IntermediateBlockData& block) {
- if (block.partition_id) {
- const int part_id = block.partition_id.value();
- const size_t num_parts = block.endpoints.size();
- return GetASTCPartition(footprint, num_parts, part_id);
- } else {
- return GenerateSinglePartition(footprint);
- }
-}
-
-Partition ComputePartition(const Footprint& footprint, const VoidExtentData&) {
- return GenerateSinglePartition(footprint);
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-LogicalASTCBlock::LogicalASTCBlock(const Footprint& footprint)
- : endpoints_(1),
- weights_(footprint.NumPixels(), 0),
- partition_(GenerateSinglePartition(footprint)) { }
-
-LogicalASTCBlock::LogicalASTCBlock(const Footprint& footprint,
- const IntermediateBlockData& block)
- : endpoints_(DecodeEndpoints(block)),
- partition_(ComputePartition(footprint, block)) {
- CalculateWeights(footprint, block);
-}
-
-LogicalASTCBlock::LogicalASTCBlock(const Footprint& footprint,
- const VoidExtentData& block)
- : endpoints_(DecodeEndpoints(block)),
- partition_(ComputePartition(footprint, block)) {
- CalculateWeights(footprint, block);
-}
-
-void LogicalASTCBlock::CalculateWeights(const Footprint& footprint,
- const IntermediateBlockData& block) {
- const int grid_size_x = block.weight_grid_dim_x;
- const int grid_size_y = block.weight_grid_dim_y;
- const int weight_grid_size = grid_size_x * grid_size_y;
-
- // Either we have a dual plane and we have twice as many weights as
- // specified or we don't
- assert(block.dual_plane_channel
- ? block.weights.size() == weight_grid_size * 2
- : block.weights.size() == weight_grid_size);
-
- std::vector<int> unquantized;
- unquantized.reserve(weight_grid_size);
-
- // According to C.2.16, if we have dual-plane weights, then we have two
- // weights per texel -- one adjacent to the other. Hence, we have to skip
- // some when we decode the separate weight values.
- const int weight_frequency = (block.dual_plane_channel) ? 2 : 1;
- const int weight_range = block.weight_range;
-
- for (int i = 0; i < weight_grid_size; ++i) {
- const int weight = block.weights[i * weight_frequency];
- unquantized.push_back(UnquantizeWeightFromRange(weight, weight_range));
- }
- weights_ = InfillWeights(unquantized, footprint, grid_size_x, grid_size_y);
-
- if (block.dual_plane_channel) {
- SetDualPlaneChannel(block.dual_plane_channel.value());
- for (int i = 0; i < weight_grid_size; ++i) {
- const int weight = block.weights[i * weight_frequency + 1];
- unquantized[i] = UnquantizeWeightFromRange(weight, weight_range);
- }
- dual_plane_->weights =
- InfillWeights(unquantized, footprint, grid_size_x, grid_size_y);
- }
-}
-
-void LogicalASTCBlock::CalculateWeights(const Footprint& footprint,
- const VoidExtentData&) {
- weights_ = std::vector<int>(footprint.NumPixels(), 0);
-}
-
-void LogicalASTCBlock::SetWeightAt(int x, int y, int weight) {
- assert(weight >= 0);
- assert(weight <= 64);
- weights_.at(y * GetFootprint().Width() + x) = weight;
-}
-
-int LogicalASTCBlock::WeightAt(int x, int y) const {
- return weights_.at(y * GetFootprint().Width() + x);
-}
-
-void LogicalASTCBlock::SetDualPlaneWeightAt(int channel, int x, int y,
- int weight) {
- assert(weight >= 0);
- assert(weight <= 64);
-
- // If it's not a dual plane, then this has no logical meaning
- assert(IsDualPlane());
-
- // If it is a dual plane and the passed channel matches the query, then we
- // return the specialized weights
- if (dual_plane_->channel == channel) {
- dual_plane_->weights.at(y * GetFootprint().Width() + x) = weight;
- } else {
- // If the channel is not the special channel, then return the general weight
- SetWeightAt(x, y, weight);
- }
-}
-
-int LogicalASTCBlock::DualPlaneWeightAt(int channel, int x, int y) const {
- // If it's not a dual plane, then we just return the weight for all channels
- if (!IsDualPlane()) {
- // TODO(google): Log warning, Requesting dual-plane channel for a non
- // dual-plane block!
- return WeightAt(x, y);
- }
-
- // If it is a dual plane and the passed channel matches the query, then we
- // return the specialized weights
- if (dual_plane_->channel == channel) {
- return dual_plane_->weights.at(y * GetFootprint().Width() + x);
- }
-
- // If the channel is not the special channel, then return the general weight
- return WeightAt(x, y);
-}
-
-void LogicalASTCBlock::SetDualPlaneChannel(int channel) {
- if (channel < 0) {
- dual_plane_.clear();
- } else if (dual_plane_) {
- dual_plane_->channel = channel;
- } else {
- dual_plane_ = DualPlaneData {channel, weights_};
- }
-}
-
-RgbaColor LogicalASTCBlock::ColorAt(int x, int y) const {
- const auto footprint = GetFootprint();
- assert(x >= 0); assert(x < footprint.Width());
- assert(y >= 0); assert(y < footprint.Height());
-
- const int texel_idx = y * footprint.Width() + x;
- const int part = partition_.assignment[texel_idx];
- const auto& endpoints = endpoints_[part];
-
- RgbaColor result;
- for (int channel = 0; channel < 4; ++channel) {
- const int weight = (dual_plane_ && dual_plane_->channel == channel)
- ? dual_plane_->weights[texel_idx]
- : weights_[texel_idx];
- const int p0 = endpoints.first[channel];
- const int p1 = endpoints.second[channel];
-
- assert(p0 >= 0); assert(p0 < 256);
- assert(p1 >= 0); assert(p1 < 256);
-
- // According to C.2.19
- const int c0 = (p0 << 8) | p0;
- const int c1 = (p1 << 8) | p1;
- const int c = (c0 * (64 - weight) + c1 * weight + 32) / 64;
- // TODO(google): Handle conversion to sRGB or FP16 per C.2.19.
- const int quantized = ((c * 255) + 32767) / 65536;
- assert(quantized < 256);
- result[channel] = quantized;
- }
-
- return result;
-}
-
-void LogicalASTCBlock::SetPartition(const Partition& p) {
- assert(p.footprint == partition_.footprint &&
- "New partitions may not be for a different footprint");
- partition_ = p;
- endpoints_.resize(p.num_parts);
-}
-
-void LogicalASTCBlock::SetEndpoints(const EndpointPair& eps, int subset) {
- assert(subset < partition_.num_parts);
- assert(subset < endpoints_.size());
-
- endpoints_[subset] = eps;
-}
-
-base::Optional<LogicalASTCBlock> UnpackLogicalBlock(
- const Footprint& footprint, const PhysicalASTCBlock& pb) {
- if (pb.IsVoidExtent()) {
- base::Optional<VoidExtentData> ve = UnpackVoidExtent(pb);
- if (!ve) {
- return {};
- }
-
- return LogicalASTCBlock(footprint, ve.value());
- } else {
- base::Optional<IntermediateBlockData> ib = UnpackIntermediateBlock(pb);
- if (!ib) {
- return {};
- }
-
- return LogicalASTCBlock(footprint, ib.value());
- }
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/logical_astc_block.h b/third-party/astc-codec/src/decoder/logical_astc_block.h
deleted file mode 100644
index 2243eb4e..00000000
--- a/third-party/astc-codec/src/decoder/logical_astc_block.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_
-#define ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_
-
-#include "src/base/optional.h"
-#include "src/decoder/footprint.h"
-#include "src/decoder/intermediate_astc_block.h"
-#include "src/decoder/partition.h"
-#include "src/decoder/physical_astc_block.h"
-
-#include <array>
-#include <utility>
-#include <vector>
-
-namespace astc_codec {
-
-// A logical ASTC block holds the endpoints, indices, and partition information
-// of a compressed block. These values generally do not adhere to any
-// quality-for-bitrate-imposed limits and are solely logical entities for
-// determining the best representation of a given block.
-class LogicalASTCBlock {
- public:
- LogicalASTCBlock(const LogicalASTCBlock&) = default;
- LogicalASTCBlock(LogicalASTCBlock&&) = default;
-
- // Unpack an intermediate block into a logical one.
- LogicalASTCBlock(const Footprint& footprint,
- const IntermediateBlockData& block);
-
- // Unpack a void extent intermediate block into a logical one.
- LogicalASTCBlock(const Footprint& footprint, const VoidExtentData& block);
-
- // Create a new, empty ASTC block
- explicit LogicalASTCBlock(const Footprint& footprint);
-
- // Returns the footprint associated with this block. The footprint is defined
- // via the partition, because the partition definition is dependent on the
- // footprint.
- const Footprint& GetFootprint() const { return partition_.footprint; }
-
- // Returns the unquantized and infilled weight in the range [0, 64] for the
- // given texel location. Assumes that the block is a single-plane block,
- // meaning that weights are used equally across all channels.
- void SetWeightAt(int x, int y, int weight);
- int WeightAt(int x, int y) const;
-
- // Returns the unquantized and infilled weight in the range [0, 64] for the
- // given channel at the given texel location. If the block does not have a
- // dual-plane channel then the reference-returning version will fail, as it
- // cannot return a reference to a value that (potentially) doesn't exist.
- void SetDualPlaneWeightAt(int channel, int x, int y, int weight);
- int DualPlaneWeightAt(int channel, int x, int y) const;
-
- // Returns the color as it would be in the given pixel coordinates of the
- // block. Fails if the coordinates are outside of the range of the block
- // footprint
- RgbaColor ColorAt(int x, int y) const;
-
- // Sets the current partition for the block. |p|'s footprint must match the
- // return value of GetFootprint() or else this call will fail.
- void SetPartition(const Partition& p);
-
- // Sets the endpoints for the given subset.
- void SetEndpoints(const EndpointPair& eps, int subset);
- void SetEndpoints(const Endpoint& ep1, const Endpoint& ep2, int subset) {
- SetEndpoints(std::make_pair(ep1, ep2), subset);
- }
-
- // Sets the dual plane channel for the block. Value must be within the range
- // [0, 3]. If a negative value is passed, then the dual-plane data for the
- // block is removed, and the block is treated as a single-plane block.
- void SetDualPlaneChannel(int channel);
- bool IsDualPlane() const { return dual_plane_.hasValue(); }
-
- private:
- // A block may have up to four endpoint pairs.
- std::vector<EndpointPair> endpoints_;
-
- // Weights are stored as values in the interval [0, 64].
- std::vector<int> weights_;
-
- // The partition information for this block. This determines the
- // appropriate subsets that each pixel should belong to.
- Partition partition_;
-
- // Dual plane data holds both the channel and the weights that describe
- // the dual plane data for the given block. If a block has a dual plane, then
- // we need to know both the channel and the weights associated with it.
- struct DualPlaneData {
- int channel;
- std::vector<int> weights;
- };
-
- // The dual-plane data is optional from a logical representation of the block.
- base::Optional<DualPlaneData> dual_plane_;
-
- // Calculates the unquantized and interpolated weights from the encoded weight
- // values and possibly dual-plane weights specified in the passed ASTC block.
- void CalculateWeights(const Footprint& footprint,
- const IntermediateBlockData& block);
-
- // Calculates the weights for a VoidExtentBlock.
- void CalculateWeights(const Footprint& footprint,
- const VoidExtentData& block);
-};
-
-// Unpacks the physical ASTC block into a logical block. Returns false if the
-// physical block is an error encoded block.
-base::Optional<LogicalASTCBlock> UnpackLogicalBlock(
- const Footprint& footprint, const PhysicalASTCBlock& pb);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_
diff --git a/third-party/astc-codec/src/decoder/partition.cc b/third-party/astc-codec/src/decoder/partition.cc
deleted file mode 100644
index 43ff6f02..00000000
--- a/third-party/astc-codec/src/decoder/partition.cc
+++ /dev/null
@@ -1,601 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/partition.h"
-#include "src/base/bottom_n.h"
-#include "src/base/utils.h"
-#include "src/decoder/footprint.h"
-
-#include <algorithm>
-#include <array>
-#include <limits>
-#include <memory>
-#include <numeric>
-#include <queue>
-#include <set>
-#include <unordered_set>
-#include <utility>
-
-namespace astc_codec {
-
-namespace {
-
-// The maximum number of partitions supported by ASTC is four.
-constexpr int kMaxNumSubsets = 4;
-
-// Partition selection function based on the ASTC specification.
-// See section C.2.21
-int SelectASTCPartition(int seed, int x, int y, int z, int partitioncount,
- int num_pixels) {
- if (partitioncount <= 1) {
- return 0;
- }
-
- if (num_pixels < 31) {
- x <<= 1;
- y <<= 1;
- z <<= 1;
- }
-
- seed += (partitioncount - 1) * 1024;
-
- uint32_t rnum = seed;
- rnum ^= rnum >> 15;
- rnum -= rnum << 17;
- rnum += rnum << 7;
- rnum += rnum << 4;
- rnum ^= rnum >> 5;
- rnum += rnum << 16;
- rnum ^= rnum >> 7;
- rnum ^= rnum >> 3;
- rnum ^= rnum << 6;
- rnum ^= rnum >> 17;
-
- uint8_t seed1 = rnum & 0xF;
- uint8_t seed2 = (rnum >> 4) & 0xF;
- uint8_t seed3 = (rnum >> 8) & 0xF;
- uint8_t seed4 = (rnum >> 12) & 0xF;
- uint8_t seed5 = (rnum >> 16) & 0xF;
- uint8_t seed6 = (rnum >> 20) & 0xF;
- uint8_t seed7 = (rnum >> 24) & 0xF;
- uint8_t seed8 = (rnum >> 28) & 0xF;
- uint8_t seed9 = (rnum >> 18) & 0xF;
- uint8_t seed10 = (rnum >> 22) & 0xF;
- uint8_t seed11 = (rnum >> 26) & 0xF;
- uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF;
-
- seed1 *= seed1;
- seed2 *= seed2;
- seed3 *= seed3;
- seed4 *= seed4;
- seed5 *= seed5;
- seed6 *= seed6;
- seed7 *= seed7;
- seed8 *= seed8;
- seed9 *= seed9;
- seed10 *= seed10;
- seed11 *= seed11;
- seed12 *= seed12;
-
- int sh1, sh2, sh3;
- if (seed & 1) {
- sh1 = (seed & 2 ? 4 : 5);
- sh2 = (partitioncount == 3 ? 6 : 5);
- } else {
- sh1 = (partitioncount == 3 ? 6 : 5);
- sh2 = (seed & 2 ? 4 : 5);
- }
- sh3 = (seed & 0x10) ? sh1 : sh2;
-
- seed1 >>= sh1;
- seed2 >>= sh2;
- seed3 >>= sh1;
- seed4 >>= sh2;
- seed5 >>= sh1;
- seed6 >>= sh2;
- seed7 >>= sh1;
- seed8 >>= sh2;
-
- seed9 >>= sh3;
- seed10 >>= sh3;
- seed11 >>= sh3;
- seed12 >>= sh3;
-
- int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14);
- int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10);
- int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 06);
- int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 02);
-
- a &= 0x3F;
- b &= 0x3F;
- c &= 0x3F;
- d &= 0x3F;
-
- if (partitioncount <= 3) {
- d = 0;
- }
- if (partitioncount <= 2) {
- c = 0;
- }
-
- if (a >= b && a >= c && a >= d) {
- return 0;
- } else if (b >= c && b >= d) {
- return 1;
- } else if (c >= d) {
- return 2;
- } else {
- return 3;
- }
-}
-
-// A partition hash that we can pass to containers like std::unordered_set
-struct PartitionHasher {
- size_t operator()(const Partition& part) const {
- // The issue here is that if we have two different partitions, A and B, then
- // their hash should be equal if A and B are equal. We define the distance
- // between A and B using PartitionMetric, but internally that finds a 1-1
- // mapping from labels in A to labels in B.
- //
- // With that in mind, when we define a hash for partitions, we need to find
- // a 1-1 mapping to a 'universal' labeling scheme. Here we define that as
- // the heuristic: the first encountered label will be 0, the second will be
- // 1, etc. This creates a unique 1-1 mapping scheme from any partition.
- //
- // Note, we can't use this heuristic for the PartitionMetric, as it will
- // generate very large discrepancies between similar labellings (for example
- // 000...001 vs 011...111). We are just looking for a boolean distinction
- // whether or not two partitions are different and don't care how different
- // they are.
- std::array<int, kMaxNumSubsets> mapping {{ -1, -1, -1, -1 }};
- int next_subset = 0;
- for (int subset : part.assignment) {
- if (mapping[subset] < 0) {
- mapping[subset] = next_subset++;
- }
- }
- assert(next_subset <= kMaxNumSubsets);
-
- // The return value will be the hash of the assignment according to this
- // mapping
- const auto seed = 0;
- return std::accumulate(part.assignment.begin(), part.assignment.end(), seed,
- [&mapping](size_t seed, const int& subset) {
- std::hash<size_t> hasher;
- const int s = mapping[subset];
- return hasher(seed) ^ hasher(static_cast<size_t>(s));
- });
- }
-};
-
-// Construct a VP-Tree of partitions. Since our PartitionMetric satisfies
-// the triangle inequality, we can use this general higher-dimensional space
-// partitioning tree to organize our partitions.
-//
-// TODO(google): !SPEED! Right now this tree stores an actual linked
-// structure of pointers which is likely very slow during construction and
-// very not cache-coherent during traversal, so it'd probably be good to
-// switch to a flattened binary tree structure if performance becomes an
-// issue.
-class PartitionTree {
- public:
- // Unclear what it means to have an uninitialized tree, so delete default
- // constructors, but allow the tree to be moved
- PartitionTree() = delete;
- PartitionTree(const PartitionTree&) = delete;
- PartitionTree(PartitionTree&& t) = default;
-
- // Generate a PartitionTree from iterators over |Partition|s
- template<typename Itr>
- PartitionTree(Itr begin, Itr end) : parts_(begin, end) {
- std::vector<int> part_indices(parts_.size());
- std::iota(part_indices.begin(), part_indices.end(), 0);
- root_ = std::unique_ptr<PartitionTreeNode>(
- new PartitionTreeNode(parts_, part_indices));
- }
-
- // Search for the k-nearest partitions that are closest to part based on
- // the result of PartitionMetric
- void Search(const Partition& part, int k,
- std::vector<const Partition*>* const results,
- std::vector<int>* const distances) const {
- ResultHeap heap(k);
- SearchNode(root_, part, &heap);
-
- results->clear();
- if (nullptr != distances) {
- distances->clear();
- }
-
- std::vector<ResultNode> search_results = heap.Pop();
- for (const auto& result : search_results) {
- results->push_back(&parts_[result.part_idx]);
- if (nullptr != distances) {
- distances->push_back(result.distance);
- }
- }
-
- assert(results->size() == k);
- }
-
- private:
- // Heap elements to be stored while searching the tree. The two relevant
- // pieces of information are the partition index and it's distance from the
- // queried partition.
- struct ResultNode {
- int part_idx;
- int distance;
-
- // Heap based on distance from query point.
- bool operator<(const ResultNode& other) const {
- return distance < other.distance;
- }
- };
-
- using ResultHeap = base::BottomN<ResultNode>;
-
- struct PartitionTreeNode {
- int part_idx;
- int split_dist;
-
- std::unique_ptr<PartitionTreeNode> left;
- std::unique_ptr<PartitionTreeNode> right;
-
- PartitionTreeNode(const std::vector<Partition> &parts,
- const std::vector<int> &part_indices)
- : split_dist(-1) {
- assert(part_indices.size() > 0);
-
- right.reset(nullptr);
- left.reset(nullptr);
-
- // Store the first node as our vantage point
- part_idx = part_indices[0];
- const Partition& vantage_point = parts[part_indices[0]];
-
- // Calculate the distances of the remaining nodes against the vantage
- // point.
- std::vector<std::pair<int, int>> part_dists;
- for (int i = 1; i < part_indices.size(); ++i) {
- const int idx = part_indices[i];
- const int dist = PartitionMetric(vantage_point, parts[idx]);
- if (dist > 0) {
- part_dists.push_back(std::make_pair(idx, dist));
- }
- }
-
- // If there are no more different parts, then this is a leaf node
- if (part_dists.empty()) {
- return;
- }
-
- struct OrderBySecond {
- typedef std::pair<int, int> PairType;
- bool operator()(const PairType& lhs, const PairType& rhs) {
- return lhs.second < rhs.second;
- }
- };
-
- // We want to partition the set such that the points are ordered
- // based on their distances from the vantage point. We can do this
- // using the partial sort of nth element.
- std::nth_element(
- part_dists.begin(), part_dists.begin() + part_dists.size() / 2,
- part_dists.end(), OrderBySecond());
-
- // Once that's done, our split position is in the middle
- const auto split_iter = part_dists.begin() + part_dists.size() / 2;
- split_dist = split_iter->second;
-
- // Recurse down the right and left sub-trees with the indices of the
- // parts that are farther and closer respectively
- std::vector<int> right_indices;
- for (auto itr = split_iter; itr != part_dists.end(); ++itr) {
- right_indices.push_back(itr->first);
- }
-
- if (!right_indices.empty()) {
- right.reset(new PartitionTreeNode(parts, right_indices));
- }
-
- std::vector<int> left_indices;
- for (auto itr = part_dists.begin(); itr != split_iter; ++itr) {
- left_indices.push_back(itr->first);
- }
-
- if (!left_indices.empty()) {
- left.reset(new PartitionTreeNode(parts, left_indices));
- }
- }
- };
-
- void SearchNode(const std::unique_ptr<PartitionTreeNode>& node,
- const Partition& p, ResultHeap* const heap) const {
- if (nullptr == node) {
- return;
- }
-
- // Calculate distance against current node
- const int dist = PartitionMetric(parts_[node->part_idx], p);
-
- // Push it onto the heap and remove the top-most nodes to maintain
- // closest k indices.
- ResultNode result;
- result.part_idx = node->part_idx;
- result.distance = dist;
- heap->Push(result);
-
- // If the split distance is uninitialized, it means we have no children.
- if (node->split_dist < 0) {
- assert(nullptr == node->left);
- assert(nullptr == node->right);
- return;
- }
-
- // Next we need to check the left and right trees if their distance
- // is closer/farther than the farthest element on the heap
- const int tau = heap->Top().distance;
- if (dist + tau < node->split_dist || dist - tau < node->split_dist) {
- SearchNode(node->left, p, heap);
- }
-
- if (dist + tau > node->split_dist || dist - tau > node->split_dist) {
- SearchNode(node->right, p, heap);
- }
- }
-
- std::vector<Partition> parts_;
- std::unique_ptr<PartitionTreeNode> root_;
-};
-
-// A helper function that generates all of the partitions for each number of
-// subsets in ASTC blocks and stores them in a PartitionTree for fast retrieval.
-const int kNumASTCPartitionIDBits = 10;
-PartitionTree GenerateASTCPartitionTree(Footprint footprint) {
- std::unordered_set<Partition, PartitionHasher> parts;
- for (int num_parts = 2; num_parts <= kMaxNumSubsets; ++num_parts) {
- for (int id = 0; id < (1 << kNumASTCPartitionIDBits); ++id) {
- Partition part = GetASTCPartition(footprint, num_parts, id);
-
- // Make sure we're not using a degenerate partition assignment that wastes
- // an endpoint pair...
- bool valid_part = true;
- for (int i = 0; i < num_parts; ++i) {
- if (std::find(part.assignment.begin(), part.assignment.end(), i) ==
- part.assignment.end()) {
- valid_part = false;
- break;
- }
- }
-
- if (valid_part) {
- parts.insert(std::move(part));
- }
- }
- }
-
- return PartitionTree(parts.begin(), parts.end());
-}
-
-// To avoid needing any fancy boilerplate for mapping from a width, height
-// tuple, we can define a simple encoding for the block mode:
-constexpr int EncodeDims(int width, int height) {
- return (width << 16) | height;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-int PartitionMetric(const Partition& a, const Partition& b) {
- // Make sure that one partition is at least a subset of the other...
- UTILS_RELEASE_ASSERT(a.footprint == b.footprint);
-
- // Make sure that the number of parts is within our limits. ASTC has a maximum
- // of four subsets per block according to the specification.
- UTILS_RELEASE_ASSERT(a.num_parts <= kMaxNumSubsets);
- UTILS_RELEASE_ASSERT(b.num_parts <= kMaxNumSubsets);
-
- const int w = a.footprint.Width();
- const int h = b.footprint.Height();
-
- struct PairCount {
- int a;
- int b;
- int count;
-
- // Comparison needed for sort below.
- bool operator>(const PairCount& other) const {
- return count > other.count;
- }
- };
-
- // Since we need to find the smallest mapping from labels in A to labels in B,
- // we need to store each label pair in a structure that can later be sorted.
- // The maximum number of subsets in an ASTC block is four, meaning that
- // between the two partitions, we can have up to sixteen different pairs.
- std::array<PairCount, 16> pair_counts;
- for (int y = 0; y < 4; ++y) {
- for (int x = 0; x < 4; ++x) {
- const int idx = y * 4 + x;
- pair_counts[idx].a = x;
- pair_counts[idx].b = y;
- pair_counts[idx].count = 0;
- }
- }
-
- // Count how many times we see each pair of assigned values (order matters!)
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < w; ++x) {
- const int idx = y * w + x;
-
- const int a_val = a.assignment[idx];
- const int b_val = b.assignment[idx];
-
- assert(a_val >= 0);
- assert(b_val >= 0);
-
- assert(a_val < 4);
- assert(b_val < 4);
-
- ++(pair_counts[b_val * 4 + a_val].count);
- }
- }
-
- // Sort the pairs in descending order based on their count
- std::sort(pair_counts.begin(), pair_counts.end(), std::greater<PairCount>());
-
- // Now assign pairs one by one until we have no more pairs to assign. Once
- // a value from A is assigned to a value in B, it can no longer be reassigned,
- // so we can keep track of this in a matrix. Similarly, to keep the assignment
- // one-to-one, once a value in B has been assigned to, it cannot be assigned
- // to again.
- std::array<std::array<bool, kMaxNumSubsets>, kMaxNumSubsets> assigned { };
-
- int pixels_matched = 0;
- for (const auto& pair_count : pair_counts) {
- bool is_assigned = false;
- for (int i = 0; i < kMaxNumSubsets; ++i) {
- is_assigned |= assigned.at(pair_count.a).at(i);
- is_assigned |= assigned.at(i).at(pair_count.b);
- }
-
- if (!is_assigned) {
- assigned.at(pair_count.a).at(pair_count.b) = true;
- pixels_matched += pair_count.count;
- }
- }
-
- // The difference is the number of pixels that had an assignment versus the
- // total number of pixels.
- return w * h - pixels_matched;
-}
-
-// Generates the partition assignment for the given block attributes.
-Partition GetASTCPartition(const Footprint& footprint, int num_parts,
- int partition_id) {
- // Partitions must have at least one subset but may have at most four
- assert(num_parts >= 0);
- assert(num_parts <= kMaxNumSubsets);
-
- // Partition ID can be no more than 10 bits.
- assert(partition_id >= 0);
- assert(partition_id < 1 << 10);
-
- Partition part = {footprint, num_parts, partition_id, /* assignment = */ {}};
- part.assignment.reserve(footprint.NumPixels());
-
- // Maintain column-major order so that we match all of the image processing
- // algorithms that depend on this class.
- for (int y = 0; y < footprint.Height(); ++y) {
- for (int x = 0; x < footprint.Width(); ++x) {
- const int p = SelectASTCPartition(partition_id, x, y, 0, num_parts,
- footprint.NumPixels());
- part.assignment.push_back(p);
- }
- }
-
- return part;
-}
-
-const std::vector<const Partition*> FindKClosestASTCPartitions(
- const Partition& candidate, int k) {
- const int encoded_dims = EncodeDims(candidate.footprint.Width(),
- candidate.footprint.Height());
-
- int index = 0;
- switch (encoded_dims) {
- case EncodeDims(4, 4): index = 0; break;
- case EncodeDims(5, 4): index = 1; break;
- case EncodeDims(5, 5): index = 2; break;
- case EncodeDims(6, 5): index = 3; break;
- case EncodeDims(6, 6): index = 4; break;
- case EncodeDims(8, 5): index = 5; break;
- case EncodeDims(8, 6): index = 6; break;
- case EncodeDims(8, 8): index = 7; break;
- case EncodeDims(10, 5): index = 8; break;
- case EncodeDims(10, 6): index = 9; break;
- case EncodeDims(10, 8): index = 10; break;
- case EncodeDims(10, 10): index = 11; break;
- case EncodeDims(12, 10): index = 12; break;
- case EncodeDims(12, 12): index = 13; break;
- default:
- assert(false && "Unknown footprint dimensions. This should have been caught sooner.");
- break;
- }
-
- static const auto* const kASTCPartitionTrees =
- new std::array<PartitionTree, Footprint::NumValidFootprints()> {{
- GenerateASTCPartitionTree(Footprint::Get4x4()),
- GenerateASTCPartitionTree(Footprint::Get5x4()),
- GenerateASTCPartitionTree(Footprint::Get5x5()),
- GenerateASTCPartitionTree(Footprint::Get6x5()),
- GenerateASTCPartitionTree(Footprint::Get6x6()),
- GenerateASTCPartitionTree(Footprint::Get8x5()),
- GenerateASTCPartitionTree(Footprint::Get8x6()),
- GenerateASTCPartitionTree(Footprint::Get8x8()),
- GenerateASTCPartitionTree(Footprint::Get10x5()),
- GenerateASTCPartitionTree(Footprint::Get10x6()),
- GenerateASTCPartitionTree(Footprint::Get10x8()),
- GenerateASTCPartitionTree(Footprint::Get10x10()),
- GenerateASTCPartitionTree(Footprint::Get12x10()),
- GenerateASTCPartitionTree(Footprint::Get12x12()),
- }};
-
- const PartitionTree& parts_vptree = kASTCPartitionTrees->at(index);
- std::vector<const Partition*> results;
- parts_vptree.Search(candidate, k, &results, nullptr);
- return results;
-}
-
-// Returns the valid ASTC partition that is closest to the candidate based on
-// the PartitionMetric defined above.
-const Partition& FindClosestASTCPartition(const Partition& candidate) {
- // Given a candidate, the closest valid partition will likely not be an exact
- // match. Consider all of the texels for which this valid partition differs
- // with the candidate.
- //
- // If the valid partition has more subsets than the candidate, then all of the
- // highest subset will be included in the mismatched texels. Since the number
- // of possible partitions with increasing subsets grows exponentially, the
- // chance that a valid partition with fewer subsets appears within the first
- // few closest partitions is relatively high. Empirically, we can usually find
- // a partition with at most |candidate.num_parts| number of subsets within the
- // first four closest partitions.
- constexpr int kSearchItems = 4;
-
- const std::vector<const Partition*> results =
- FindKClosestASTCPartitions(candidate, kSearchItems);
-
- // Optimistically, look for result with the same number of subsets.
- for (const auto& result : results) {
- if (result->num_parts == candidate.num_parts) {
- return *result;
- }
- }
-
- // If all else fails, then at least find the result with fewer subsets than
- // we asked for.
- for (const auto& result : results) {
- if (result->num_parts < candidate.num_parts) {
- return *result;
- }
- }
-
- assert(false &&
- "Could not find partition with acceptable number of subsets!");
- return *(results[0]);
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/partition.h b/third-party/astc-codec/src/decoder/partition.h
deleted file mode 100644
index 4f64acb8..00000000
--- a/third-party/astc-codec/src/decoder/partition.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_PARTITION_H_
-#define ASTC_CODEC_DECODER_PARTITION_H_
-
-#include "src/base/optional.h"
-#include "src/decoder/footprint.h"
-
-#include <vector>
-
-namespace astc_codec {
-
-struct Partition;
-
-// Determines the "difference" between any two partitions of the same size.
-// This metric attempts to find the best one to one mapping from the labels in
-// partition a against the labels in partition b. Once that mapping is found, it
-// returns the number of pixels that are mismatched between the two. Each
-// partition is expected to start in the upper left corner of the block and
-// proceed in raster-scan order. Two partitions are equal if the mapping is
-// bijective. This metric is a metric in the mathematical sense. In other words
-// it has the following properties:
-//
-// 1) PartitionMetric(a, b) >= 0
-// 2) PartitionMetric(a, b) == PartitionMetric(b, a)
-// 3) PartitionMetric(a, b) == 0 iff a == b
-// 4) PartitionMetric(a, b) + PartitionMetric(b, c) >= PartitionMetric(a, c)
-//
-// Throws an error if one partition's footprint is not equal to the other.
-int PartitionMetric(const Partition& a, const Partition& b);
-
-// A partition is a way to divide up an ASTC block into disjoint subsets such
-// that each subset uses a different set of endpoints. This is used to increase
-// the compression quality of blocks. One way to store such a partition is to
-// assign an ID to use with a predetermined decoding method. Here we store the
-// logical representation of partitions by keeping a per-pixel label. All pixels
-// that share a label belong to the same subset.
-struct Partition {
- // The footprint width and height of this partition. This determines the size
- // of the assignment array.
- Footprint footprint;
-
- // The number of subsets in this partition. The values in the partition
- // assignment fall within the range [0, num_parts). The maximum number of
- // parts supported is four.
- int num_parts;
-
- // The 10-bit partition ID as stored in bits 13-22 of multi-part ASTC blocks.
- // (See Section C.2.9) If there is no guarantee that this partition is a valid
- // ASTC partition, this should be set to absl::nullopt.
- base::Optional<int> partition_id;
-
- // A value in the range [0, num_parts) corresponding to the label for
- // the given texel (x, y) in [0, footprint_width) x [0, footprint_height)
- // using a raster-order layout.
- std::vector<int> assignment;
-
- // Returns true only if their "distance" is zero, i.e. if they have compatible
- // subset assignments.
- bool operator==(const Partition& other) const {
- return PartitionMetric(*this, other) == 0;
- }
-};
-
-// Generates the ASTC partition assignment for the given block attributes.
-Partition GetASTCPartition(const Footprint& footprint, int num_parts,
- int partition_id);
-
-// Returns the |k| valid ASTC partitions that are closest to the candidate based
-// on the PartitionMetric defined above.
-const std::vector<const Partition*> FindKClosestASTCPartitions(
- const Partition& candidate, int k);
-
-// Returns the valid ASTC partition closest to the candidate with at most as
-// many subsets as the |candidate|. Note: this is not a deterministic function,
-// as the underlying valid partitions are sorted using a hash map and a distance
-// function whose range is the natural numbers. The chances that two or more
-// partitions are equally 'closest' is possible, in which case this function
-// makes no guarantees about which one it will return. For more control, use
-// FindKClosestASTCPartitions above.
-const Partition& FindClosestASTCPartition(const Partition& candidate);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_PARTITION_H_
diff --git a/third-party/astc-codec/src/decoder/physical_astc_block.cc b/third-party/astc-codec/src/decoder/physical_astc_block.cc
deleted file mode 100644
index 7cc4d8e5..00000000
--- a/third-party/astc-codec/src/decoder/physical_astc_block.cc
+++ /dev/null
@@ -1,761 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/physical_astc_block.h"
-#include "src/base/math_utils.h"
-#include "src/base/optional.h"
-#include "src/base/uint128.h"
-#include "src/decoder/integer_sequence_codec.h"
-
-#include <array>
-#include <cmath>
-
-namespace astc_codec {
-
-namespace {
-
-static_assert(static_cast<int>(ColorEndpointMode::kNumColorEndpointModes) == 16,
- "There are only sixteen color endpoint modes defined in the "
- "ASTC specification. If this is false, then the enum may be "
- "incorrect.");
-
-constexpr int kASTCBlockSizeBits = 128;
-constexpr int kASTCBlockSizeBytes = kASTCBlockSizeBits / 8;
-constexpr uint32_t kVoidExtentMaskBits = 9;
-constexpr uint32_t kVoidExtentMask = 0x1FC;
-constexpr int kWeightGridMinBitLength = 24;
-constexpr int kWeightGridMaxBitLength = 96;
-constexpr int kMaxNumPartitions = 4;
-constexpr int kMaxNumWeights = 64;
-
-// These are the overall block modes defined in table C.2.8. There are 10
-// weight grid encoding schemes + void extent.
-enum class BlockMode {
- kB4_A2,
- kB8_A2,
- kA2_B8,
- kA2_B6,
- kB2_A2,
- k12_A2,
- kA2_12,
- k6_10,
- k10_6,
- kA6_B6,
- kVoidExtent,
-};
-
-struct WeightGridProperties {
- int width;
- int height;
- int range;
-};
-
-// Local function prototypes
-base::Optional<BlockMode> DecodeBlockMode(const base::UInt128 astc_bits);
-base::Optional<WeightGridProperties> DecodeWeightProps(
- const base::UInt128 astc_bits, std::string* error);
-std::array<int, 4> DecodeVoidExtentCoords(const base::UInt128 astc_bits);
-bool DecodeDualPlaneBit(const base::UInt128 astc_bits);
-int DecodeNumPartitions(const base::UInt128 astc_bits);
-int DecodeNumWeightBits(const base::UInt128 astc_bits);
-int DecodeDualPlaneBitStartPos(const base::UInt128 astc_bits);
-ColorEndpointMode DecodeEndpointMode(const base::UInt128 astc_bits,
- int partition);
-int DecodeNumColorValues(const base::UInt128 astc_bits);
-
-// Returns the block mode, if it's valid.
-base::Optional<BlockMode> DecodeBlockMode(const base::UInt128 astc_bits) {
- using Result = base::Optional<BlockMode>;
- const uint64_t low_bits = astc_bits.LowBits();
- if (base::GetBits(low_bits, 0, kVoidExtentMaskBits) == kVoidExtentMask) {
- return Result(BlockMode::kVoidExtent);
- }
-
- if (base::GetBits(low_bits, 0, 2) != 0) {
- const uint64_t mode_bits = base::GetBits(low_bits, 2, 2);
- switch (mode_bits) {
- case 0: return Result(BlockMode::kB4_A2);
- case 1: return Result(BlockMode::kB8_A2);
- case 2: return Result(BlockMode::kA2_B8);
- case 3: return base::GetBits(low_bits, 8, 1) ?
- Result(BlockMode::kB2_A2) : Result(BlockMode::kA2_B6);
- }
- } else {
- const uint64_t mode_bits = base::GetBits(low_bits, 5, 4);
- if ((mode_bits & 0xC) == 0x0) {
- if (base::GetBits(low_bits, 0, 4) == 0) {
- // Reserved.
- return Result();
- } else {
- return Result(BlockMode::k12_A2);
- }
- } else if ((mode_bits & 0xC) == 0x4) {
- return Result(BlockMode::kA2_12);
- } else if (mode_bits == 0xC) {
- return Result(BlockMode::k6_10);
- } else if (mode_bits == 0xD) {
- return Result(BlockMode::k10_6);
- } else if ((mode_bits & 0xC) == 0x8) {
- return Result(BlockMode::kA6_B6);
- }
- }
-
- return Result();
-}
-
-base::Optional<WeightGridProperties> DecodeWeightProps(
- const base::UInt128 astc_bits, std::string* error) {
- auto block_mode = DecodeBlockMode(astc_bits);
- if (!block_mode) {
- *error = "Reserved block mode";
- return {};
- }
-
- // The dimensions of the weight grid and their range
- WeightGridProperties props;
-
- // Determine the weight extents based on the block mode
- const uint32_t low_bits =
- static_cast<uint32_t>(astc_bits.LowBits() & 0xFFFFFFFF);
- switch (block_mode.value()) {
- case BlockMode::kB4_A2: {
- int a = base::GetBits(low_bits, 5, 2);
- int b = base::GetBits(low_bits, 7, 2);
- props.width = b + 4;
- props.height = a + 2;
- }
- break;
-
- case BlockMode::kB8_A2: {
- int a = base::GetBits(low_bits, 5, 2);
- int b = base::GetBits(low_bits, 7, 2);
- props.width = b + 8;
- props.height = a + 2;
- }
- break;
-
- case BlockMode::kA2_B8: {
- int a = base::GetBits(low_bits, 5, 2);
- int b = base::GetBits(low_bits, 7, 2);
- props.width = a + 2;
- props.height = b + 8;
- }
- break;
-
- case BlockMode::kA2_B6: {
- int a = base::GetBits(low_bits, 5, 2);
- int b = base::GetBits(low_bits, 7, 1);
- props.width = a + 2;
- props.height = b + 6;
- }
- break;
-
- case BlockMode::kB2_A2: {
- int a = base::GetBits(low_bits, 5, 2);
- int b = base::GetBits(low_bits, 7, 1);
- props.width = b + 2;
- props.height = a + 2;
- }
- break;
-
- case BlockMode::k12_A2: {
- int a = base::GetBits(low_bits, 5, 2);
- props.width = 12;
- props.height = a + 2;
- }
- break;
-
- case BlockMode::kA2_12: {
- int a = base::GetBits(low_bits, 5, 2);
- props.width = a + 2;
- props.height = 12;
- }
- break;
-
- case BlockMode::k6_10: {
- props.width = 6;
- props.height = 10;
- }
- break;
-
- case BlockMode::k10_6: {
- props.width = 10;
- props.height = 6;
- }
- break;
-
- case BlockMode::kA6_B6: {
- int a = base::GetBits(low_bits, 5, 2);
- int b = base::GetBits(low_bits, 9, 2);
- props.width = a + 6;
- props.height = b + 6;
- }
- break;
-
- // Void extent blocks have no weight grid.
- case BlockMode::kVoidExtent:
- *error = "Void extent block has no weight grid";
- return {};
-
- // We have a valid block mode which isn't a void extent? We
- // should be able to decode the weight grid dimensions.
- default:
- assert(false && "Error decoding weight grid");
- *error = "Internal error";
- return {};
- }
-
- // Determine the weight range based on the block mode
- uint32_t r = base::GetBits(low_bits, 4, 1);
- switch (block_mode.value()) {
- case BlockMode::kB4_A2:
- case BlockMode::kB8_A2:
- case BlockMode::kA2_B8:
- case BlockMode::kA2_B6:
- case BlockMode::kB2_A2: {
- r |= base::GetBits(low_bits, 0, 2) << 1;
- }
- break;
-
- case BlockMode::k12_A2:
- case BlockMode::kA2_12:
- case BlockMode::k6_10:
- case BlockMode::k10_6:
- case BlockMode::kA6_B6: {
- r |= base::GetBits(low_bits, 2, 2) << 1;
- }
- break;
-
- // We have a valid block mode which doesn't have weights? We
- // should have caught this earlier.
- case BlockMode::kVoidExtent:
- default:
- assert(false && "Error decoding weight grid");
- *error = "Internal error";
- return {};
- }
-
- // Decode the range...
- // High bit is in bit 9 unless we're using a particular block mode
- uint32_t h = base::GetBits(low_bits, 9, 1);
- if (block_mode == BlockMode::kA6_B6) {
- h = 0;
- }
-
- // Figure out the range of the weights (Table C.2.7)
- constexpr std::array<int, 16> kWeightRanges = {{
- -1, -1, 1, 2, 3, 4, 5, 7, -1, -1, 9, 11, 15, 19, 23, 31
- }};
-
- assert(((h << 3) | r) < kWeightRanges.size());
-
- props.range = kWeightRanges.at((h << 3) | r);
- if (props.range < 0) {
- *error = "Reserved range for weight bits";
- return {};
- }
-
- // Error checking -- do we have too many weights?
- int num_weights = props.width * props.height;
- if (DecodeDualPlaneBit(astc_bits)) {
- num_weights *= 2;
- }
-
- if (kMaxNumWeights < num_weights) {
- *error = "Too many weights specified";
- return {};
- }
-
- // Do we have too many weight bits?
- const int bit_count =
- IntegerSequenceCodec::GetBitCountForRange(num_weights, props.range);
-
- if (bit_count < kWeightGridMinBitLength) {
- *error = "Too few bits required for weight grid";
- return {};
- }
-
- if (kWeightGridMaxBitLength < bit_count) {
- *error = "Too many bits required for weight grid";
- return {};
- }
-
- return props;
-}
-
-// Returns the four 13-bit integers that define the range of texture
-// coordinates present in a void extent block as defined in Section
-// C.2.23 of the specification. The coordinates returned are of
-// the form (min_s, max_s, min_t, max_t)
-std::array<int, 4> DecodeVoidExtentCoords(const base::UInt128 astc_bits) {
- const uint64_t low_bits = astc_bits.LowBits();
-
- std::array<int, 4> coords;
- for (int i = 0; i < 4; ++i) {
- coords[i] = static_cast<int>(base::GetBits(low_bits, 12 + 13 * i, 13));
- }
-
- return coords;
-}
-
-bool DecodeDualPlaneBit(const base::UInt128 astc_bits) {
- base::Optional<BlockMode> block_mode = DecodeBlockMode(astc_bits);
-
- // Void extent blocks certainly aren't dual-plane.
- if (block_mode == BlockMode::kVoidExtent) {
- return false;
- }
-
- // One special block mode doesn't have any dual plane bit
- if (block_mode == BlockMode::kA6_B6) {
- return false;
- }
-
- // Otherwise, dual plane is determined by the 10th bit.
- constexpr int kDualPlaneBitPosition = 10;
- return base::GetBits(astc_bits, kDualPlaneBitPosition, 1) != 0;
-}
-
-int DecodeNumPartitions(const base::UInt128 astc_bits) {
- constexpr int kNumPartitionsBitPosition = 11;
- constexpr int kNumPartitionsBitLength = 2;
-
- // Non-void extent blocks
- const uint64_t low_bits = astc_bits.LowBits();
- const int num_partitions = 1 + static_cast<int>(
- base::GetBits(low_bits,
- kNumPartitionsBitPosition,
- kNumPartitionsBitLength));
- assert(num_partitions > 0);
- assert(num_partitions <= kMaxNumPartitions);
-
- return num_partitions;
-}
-
-int DecodeNumWeightBits(const base::UInt128 astc_bits) {
- std::string error;
- auto maybe_weight_props = DecodeWeightProps(astc_bits, &error);
- if (!maybe_weight_props.hasValue()) {
- return 0; // No weights? No weight bits...
- }
-
- const auto weight_props = maybe_weight_props.value();
-
- // Figure out the number of weights
- int num_weights = weight_props.width * weight_props.height;
- if (DecodeDualPlaneBit(astc_bits)) {
- num_weights *= 2;
- }
-
- // The number of bits is determined by the number of values
- // that are going to be encoded using the given ise_counts.
- return IntegerSequenceCodec::GetBitCountForRange(
- num_weights, weight_props.range);
-}
-
-// Returns the number of bits after the weight data used to
-// store additional CEM bits.
-int DecodeNumExtraCEMBits(const base::UInt128 astc_bits) {
- const int num_partitions = DecodeNumPartitions(astc_bits);
-
- // Do we only have one partition?
- if (num_partitions == 1) {
- return 0;
- }
-
- // Do we have a shared CEM?
- constexpr int kSharedCEMBitPosition = 23;
- constexpr int kSharedCEMBitLength = 2;
- const base::UInt128 shared_cem =
- base::GetBits(astc_bits, kSharedCEMBitPosition, kSharedCEMBitLength);
- if (shared_cem == 0) {
- return 0;
- }
-
- const std::array<int, 4> extra_cem_bits_for_partition = {{ 0, 2, 5, 8 }};
- return extra_cem_bits_for_partition[num_partitions - 1];
-}
-
-// Returns the starting position of the dual plane channel. This comes
-// before the weight data and extra CEM bits.
-int DecodeDualPlaneBitStartPos(const base::UInt128 astc_bits) {
- const int start_pos = kASTCBlockSizeBits
- - DecodeNumWeightBits(astc_bits)
- - DecodeNumExtraCEMBits(astc_bits);
-
- if (DecodeDualPlaneBit(astc_bits)) {
- return start_pos - 2;
- } else {
- return start_pos;
- }
-}
-
-// Decodes a CEM mode based on the partition number.
-ColorEndpointMode DecodeEndpointMode(const base::UInt128 astc_bits,
- int partition) {
- int num_partitions = DecodeNumPartitions(astc_bits);
- assert(partition >= 0);
- assert(partition < num_partitions);
-
- // Do we only have one partition?
- uint64_t low_bits = astc_bits.LowBits();
- if (num_partitions == 1) {
- uint64_t cem = base::GetBits(low_bits, 13, 4);
- return static_cast<ColorEndpointMode>(cem);
- }
-
- // More than one partition ... do we have a shared CEM?
- if (DecodeNumExtraCEMBits(astc_bits) == 0) {
- const uint64_t shared_cem = base::GetBits(low_bits, 25, 4);
- return static_cast<ColorEndpointMode>(shared_cem);
- }
-
- // More than one partition and no shared CEM...
- uint64_t cem = base::GetBits(low_bits, 23, 6);
- const int base_cem = static_cast<int>(((cem & 0x3) - 1) * 4);
- cem >>= 2; // Skip the base CEM bits
-
- // The number of extra CEM bits at the end of the weight grid is
- // determined by the number of partitions and what the base cem mode is...
- const int num_extra_cem_bits = DecodeNumExtraCEMBits(astc_bits);
- const int extra_cem_start_pos = kASTCBlockSizeBits
- - num_extra_cem_bits
- - DecodeNumWeightBits(astc_bits);
-
- base::UInt128 extra_cem =
- base::GetBits(astc_bits, extra_cem_start_pos, num_extra_cem_bits);
- cem |= extra_cem.LowBits() << 4;
-
- // Decode C and M per Figure C.4
- int c = -1, m = -1;
- for (int i = 0; i < num_partitions; ++i) {
- if (i == partition) {
- c = cem & 0x1;
- }
- cem >>= 1;
- }
-
- for (int i = 0; i < num_partitions; ++i) {
- if (i == partition) {
- m = cem & 0x3;
- }
- cem >>= 2;
- }
-
- assert(c >= 0);
- assert(m >= 0);
-
- // Compute the mode based on C and M
- const int mode = base_cem + 4 * c + m;
- assert(mode < static_cast<int>(ColorEndpointMode::kNumColorEndpointModes));
- return static_cast<ColorEndpointMode>(mode);
-}
-
-int DecodeNumColorValues(const base::UInt128 astc_bits) {
- int num_color_values = 0;
- auto num_partitions = DecodeNumPartitions(astc_bits);
- for (int i = 0; i < num_partitions; ++i) {
- ColorEndpointMode endpoint_mode = DecodeEndpointMode(astc_bits, i);
- num_color_values += NumColorValuesForEndpointMode(endpoint_mode);
- }
-
- return num_color_values;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-static_assert(sizeof(PhysicalASTCBlock) == PhysicalASTCBlock::kSizeInBytes,
- "The size of the struct should be the size of the block so that"
- "we can effectively use them contiguously in memory.");
-
-PhysicalASTCBlock::PhysicalASTCBlock(const base::UInt128 astc_block)
- : astc_bits_(astc_block) {}
-
-PhysicalASTCBlock::PhysicalASTCBlock(const std::string& encoded_block)
- : astc_bits_([&encoded_block]() {
- assert(encoded_block.size() == PhysicalASTCBlock::kSizeInBytes);
- base::UInt128 astc_bits = 0;
- int shift = 0;
- for (const unsigned char c : encoded_block) {
- astc_bits |= base::UInt128(static_cast<uint64_t>(c)) << shift;
- shift += 8;
- }
- return astc_bits;
- }())
-{ }
-
-base::Optional<std::string> PhysicalASTCBlock::IsIllegalEncoding() const {
- // If the block is not a void extent block, then it must have
- // weights specified. DecodeWeightProps will return the weight specifications
- // if they exist and are legal according to C.2.24, and will otherwise be
- // empty.
- base::Optional<BlockMode> block_mode = DecodeBlockMode(astc_bits_);
- if (block_mode != BlockMode::kVoidExtent) {
- std::string error;
- auto maybe_weight_props = DecodeWeightProps(astc_bits_, &error);
- if (!maybe_weight_props.hasValue()) {
- return error;
- }
- }
-
- // Check void extent blocks...
- if (block_mode == BlockMode::kVoidExtent) {
- // ... for reserved bits incorrectly set
- if (base::GetBits(astc_bits_, 10, 2) != 0x3) {
- return std::string("Reserved bits set for void extent block");
- }
-
- // ... for incorrectly defined texture coordinates
- std::array<int, 4> coords = DecodeVoidExtentCoords(astc_bits_);
-
- bool coords_all_1s = true;
- for (const auto coord : coords) {
- coords_all_1s &= coord == ((1 << 13) - 1);
- }
-
- if (!coords_all_1s && (coords[0] >= coords[1] || coords[2] >= coords[3])) {
- return std::string("Void extent texture coordinates are invalid");
- }
- }
-
- // If the number of color values exceeds a threshold and it isn't a void
- // extent block then we've run into an error
- if (block_mode != BlockMode::kVoidExtent) {
- int num_color_vals = DecodeNumColorValues(astc_bits_);
- if (num_color_vals > 18) {
- return std::string("Too many color values");
- }
-
- // The maximum number of available color bits is the number of
- // bits between the dual plane bits and the base CEM. This must
- // be larger than a threshold defined in C.2.24.
-
- // Dual plane bit starts after weight bits and CEM
- const int num_partitions = DecodeNumPartitions(astc_bits_);
- const int dual_plane_start_pos = DecodeDualPlaneBitStartPos(astc_bits_);
- const int color_start_bit = (num_partitions == 1) ? 17 : 29;
-
- const int required_color_bits = ((13 * num_color_vals) + 4) / 5;
- const int available_color_bits = dual_plane_start_pos - color_start_bit;
- if (available_color_bits < required_color_bits) {
- return std::string("Not enough color bits");
- }
-
- // If we have four partitions and a dual plane then we have a problem.
- if (num_partitions == 4 && DecodeDualPlaneBit(astc_bits_)) {
- return std::string("Both four partitions and dual plane specified");
- }
- }
-
- // Otherwise we're OK
- return { };
-}
-
-bool PhysicalASTCBlock::IsVoidExtent() const {
- // If it's an error block, it's not a void extent block.
- if (IsIllegalEncoding()) {
- return false;
- }
-
- return DecodeBlockMode(astc_bits_) == BlockMode::kVoidExtent;
-}
-
-base::Optional<std::array<int, 4>> PhysicalASTCBlock::VoidExtentCoords() const {
- if (IsIllegalEncoding() || !IsVoidExtent()) {
- return { };
- }
-
- // If void extent coords are all 1's then these are not valid void extent
- // coords
- const uint64_t ve_mask = 0xFFFFFFFFFFFFFDFFULL;
- const uint64_t const_blk_mode = 0xFFFFFFFFFFFFFDFCULL;
- if ((ve_mask & astc_bits_.LowBits()) == const_blk_mode) {
- return {};
- }
-
- return DecodeVoidExtentCoords(astc_bits_);
-}
-
-bool PhysicalASTCBlock::IsDualPlane() const {
- // If it's an error block, then we aren't a dual plane block
- if (IsIllegalEncoding()) {
- return false;
- }
-
- return DecodeDualPlaneBit(astc_bits_);
-}
-
-// Returns the number of weight bits present in this block
-base::Optional<int> PhysicalASTCBlock::NumWeightBits() const {
- // If it's an error block, then we have no weight bits.
- if (IsIllegalEncoding()) return { };
-
- // If it's a void extent block, we have no weight bits
- if (IsVoidExtent()) return { };
-
- return DecodeNumWeightBits(astc_bits_);
-}
-
-base::Optional<int> PhysicalASTCBlock::WeightStartBit() const {
- if (IsIllegalEncoding()) return { };
- if (IsVoidExtent()) return { };
-
- return kASTCBlockSizeBits - DecodeNumWeightBits(astc_bits_);
-}
-
-base::Optional<std::array<int, 2>> PhysicalASTCBlock::WeightGridDims() const {
- std::string error;
- auto weight_props = DecodeWeightProps(astc_bits_, &error);
-
- if (!weight_props.hasValue()) return { };
- if (IsIllegalEncoding()) return { };
-
- const auto props = weight_props.value();
- return {{{ props.width, props.height }}};
-}
-
-base::Optional<int> PhysicalASTCBlock::WeightRange() const {
- std::string error;
- auto weight_props = DecodeWeightProps(astc_bits_, &error);
-
- if (!weight_props.hasValue()) return { };
- if (IsIllegalEncoding()) return { };
-
- return weight_props.value().range;
-}
-
-base::Optional<int> PhysicalASTCBlock::DualPlaneChannel() const {
- if (!IsDualPlane()) return { };
-
- int dual_plane_start_pos = DecodeDualPlaneBitStartPos(astc_bits_);
- auto plane_bits = base::GetBits(astc_bits_, dual_plane_start_pos, 2);
- return base::Optional<int>(static_cast<int>(plane_bits.LowBits()));
-}
-
-base::Optional<int> PhysicalASTCBlock::ColorStartBit() const {
- if (IsVoidExtent()) {
- return 64;
- }
-
- auto num_partitions = NumPartitions();
- if (!num_partitions) return { };
-
- return (num_partitions == 1) ? 17 : 29;
-}
-
-base::Optional<int> PhysicalASTCBlock::NumColorValues() const {
- // If we have a void extent block, then we have four color values
- if (IsVoidExtent()) {
- return 4;
- }
-
- // If we have an illegal encoding, then we have no color values
- if (IsIllegalEncoding()) return { };
-
- return DecodeNumColorValues(astc_bits_);
-}
-
-void PhysicalASTCBlock::GetColorValuesInfo(int* const color_bits,
- int* const color_range) const {
- // Figure out the range possible for the number of values we have...
- const int dual_plane_start_pos = DecodeDualPlaneBitStartPos(astc_bits_);
- const int max_color_bits = dual_plane_start_pos - ColorStartBit().value();
- const int num_color_values = NumColorValues().value();
- for (int range = 255; range > 0; --range) {
- const int bitcount =
- IntegerSequenceCodec::GetBitCountForRange(num_color_values, range);
- if (bitcount <= max_color_bits) {
- if (color_bits != nullptr) {
- *color_bits = bitcount;
- }
-
- if (color_range != nullptr) {
- *color_range = range;
- }
- return;
- }
- }
-
- assert(false &&
- "This means that even if we have a range of one there aren't "
- "enough bits to store the color values, and our encoding is "
- "illegal.");
-}
-
-base::Optional<int> PhysicalASTCBlock::NumColorBits() const {
- if (IsIllegalEncoding()) return { };
-
- if (IsVoidExtent()) {
- return 64;
- }
-
- int color_bits;
- GetColorValuesInfo(&color_bits, nullptr);
- return color_bits;
-}
-
-base::Optional<int> PhysicalASTCBlock::ColorValuesRange() const {
- if (IsIllegalEncoding()) return { };
-
- if (IsVoidExtent()) {
- return (1 << 16) - 1;
- }
-
- int color_range;
- GetColorValuesInfo(nullptr, &color_range);
- return color_range;
-}
-
-base::Optional<int> PhysicalASTCBlock::NumPartitions() const {
- // Error blocks have no partitions
- if (IsIllegalEncoding()) return { };
-
- // Void extent blocks have no partitions either
- if (DecodeBlockMode(astc_bits_) == BlockMode::kVoidExtent) {
- return { };
- }
-
- // All others have some number of partitions
- return DecodeNumPartitions(astc_bits_);
-}
-
-base::Optional<int> PhysicalASTCBlock::PartitionID() const {
- auto num_partitions = NumPartitions();
- if (!num_partitions || num_partitions == 1) return { };
-
- const uint64_t low_bits = astc_bits_.LowBits();
- return static_cast<int>(base::GetBits(low_bits, 13, 10));
-}
-
-base::Optional<ColorEndpointMode> PhysicalASTCBlock::GetEndpointMode(
- int partition) const {
- // Error block?
- if (IsIllegalEncoding()) return { };
-
- // Void extent blocks have no endpoint modes
- if (DecodeBlockMode(astc_bits_) == BlockMode::kVoidExtent) {
- return { };
- }
-
- // Do we even have a CEM for this partition?
- if (partition < 0 || DecodeNumPartitions(astc_bits_) <= partition) {
- return { };
- }
-
- return DecodeEndpointMode(astc_bits_, partition);
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/physical_astc_block.h b/third-party/astc-codec/src/decoder/physical_astc_block.h
deleted file mode 100644
index 1b04bdda..00000000
--- a/third-party/astc-codec/src/decoder/physical_astc_block.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_
-#define ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_
-
-// The logic in this file is based on the ASTC specification, which can be
-// found here:
-// https://www.opengl.org/registry/specs/KHR/texture_compression_astc_hdr.txt
-
-#include "src/base/optional.h"
-#include "src/base/uint128.h"
-#include "src/decoder/types.h"
-
-#include <string>
-
-namespace astc_codec {
-
-// A PhysicalASTCBlock contains all 128 bits and the logic for decoding the
-// various internals of an ASTC block.
-class PhysicalASTCBlock {
- public:
- // The physical size in bytes of an ASTC block
- static const size_t kSizeInBytes = 16;
-
- // Initializes an ASTC block based on the encoded string.
- explicit PhysicalASTCBlock(const std::string& encoded_block);
- explicit PhysicalASTCBlock(const base::UInt128 astc_block);
-
- // Returns the 128 bits of this ASTC block.
- base::UInt128 GetBlockBits() const { return astc_bits_; }
-
- // Weights are stored in a grid that may not have the same dimensions
- // as the block dimensions. This allows us to see what the physical
- // dimensions are of the grid.
- base::Optional<std::array<int, 2>> WeightGridDims() const;
-
- // The weight range is the maximum value a weight can take in the
- // weight grid.
- base::Optional<int> WeightRange() const;
-
- // Returns true if the block encoding specifies a void-extent block. This
- // kind of block stores a single color to be used for every pixel in the
- // block.
- bool IsVoidExtent() const;
-
- // Returns the values (min_s, max_s, min_t, max_t) as defined in the void
- // extent block as the range of texture coordinates for which this block is
- // defined. (See Section C.2.23)
- base::Optional<std::array<int, 4>> VoidExtentCoords() const;
-
- // Returns true if the block contains two separate weight grids. One used
- // for the channel returned by DualPlaneChannel() and one used by the other
- // channels.
- bool IsDualPlane() const;
-
- // Returns the channel used as the "dual plane". The return value is only
- // meaningful if IsDualPlane() returns true...
- base::Optional<int> DualPlaneChannel() const;
-
- // Returns a reason that the encoding doesn't adhere to the specification.
- // If the encoding is legal, then this returns a nullptr. This allows us to
- // still use code of the form:
- //
- // if (IsIllegalEncoding()) {
- // ... error ...
- // }
- // ... no error ...
- //
- // However, it also helps with debugging since we can find problems with
- // encodings a lot faster.
- base::Optional<std::string> IsIllegalEncoding() const;
-
- // Returns the number of weight bits present in this block.
- base::Optional<int> NumWeightBits() const;
-
- // Returns the starting position within the range [0, 127] of the
- // weight data within the block.
- base::Optional<int> WeightStartBit() const;
-
- // Returns the number of endpoint pairs used in this block.
- base::Optional<int> NumPartitions() const;
-
- // Returns the seed used to determine the partition for a given
- // (x, y) coordinate within the block. Determined using the
- // block size and the function as described in the specification.
- base::Optional<int> PartitionID() const;
-
- // Returns the color endpoint mode for the given partition index.
- base::Optional<ColorEndpointMode> GetEndpointMode(int partition) const;
-
- // Returns the starting position within the range [0, 127] of the
- // color data within the block.
- base::Optional<int> ColorStartBit() const;
-
- // Returns the number of integers used to represent the color endpoints.
- base::Optional<int> NumColorValues() const;
-
- // Returns the number of bits used to represent the color endpoints.
- base::Optional<int> NumColorBits() const;
-
- // Returns the maximum value that each of the encoded integers used to
- // represent the color endpoints can take.
- base::Optional<int> ColorValuesRange() const;
-
- private:
- const base::UInt128 astc_bits_;
-
- // The logic to return the number of color bits and the color values range
- // is very similar, so it's probably best to abstract it away into its own
- // function.
- void GetColorValuesInfo(int* color_bits, int* color_range) const;
-};
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_
diff --git a/third-party/astc-codec/src/decoder/quantization.cc b/third-party/astc-codec/src/decoder/quantization.cc
deleted file mode 100644
index db996826..00000000
--- a/third-party/astc-codec/src/decoder/quantization.cc
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/quantization.h"
-#include "src/base/math_utils.h"
-
-#include <algorithm>
-#include <array>
-#include <cassert>
-#include <map>
-#include <memory>
-#include <vector>
-
-namespace astc_codec {
-
-namespace {
-
-// Trit unquantization procedure as described in Section C.2.13
-int GetUnquantizedTritValue(int trit, int bits, int range) {
- int a = (bits & 1) ? 0x1FF : 0;
- int b = 0, c = 0;
- switch (range) {
- case 5: {
- b = 0;
- c = 204;
- }
- break;
-
- case 11: {
- int x = (bits >> 1) & 0x1;
- b = (x << 1) | (x << 2) | (x << 4) | (x << 8);
- c = 93;
- }
- break;
-
- case 23: {
- int x = (bits >> 1) & 0x3;
- b = x | (x << 2) | (x << 7);
- c = 44;
- }
- break;
-
- case 47: {
- int x = (bits >> 1) & 0x7;
- b = x | (x << 6);
- c = 22;
- }
- break;
-
- case 95: {
- int x = (bits >> 1) & 0xF;
- b = (x >> 2) | (x << 5);
- c = 11;
- }
- break;
-
- case 191: {
- int x = (bits >> 1) & 0x1F;
- b = (x >> 4) | (x << 4);
- c = 5;
- }
- break;
-
- default:
- assert(false && "Illegal trit encoding");
- break;
- }
-
- int t = trit * c + b;
- t ^= a;
- t = (a & 0x80) | (t >> 2);
- return t;
-}
-
-// Quint unquantization procedure as described in Section C.2.13
-int GetUnquantizedQuintValue(int quint, int bits, int range) {
- int a = (bits & 1) ? 0x1FF : 0;
- int b = 0, c = 0;
- switch (range) {
- case 9: {
- b = 0;
- c = 113;
- }
- break;
-
- case 19: {
- int x = (bits >> 1) & 0x1;
- b = (x << 2) | (x << 3) | (x << 8);
- c = 54;
- }
- break;
-
- case 39: {
- int x = (bits >> 1) & 0x3;
- b = (x >> 1) | (x << 1) | (x << 7);
- c = 26;
- }
- break;
-
- case 79: {
- int x = (bits >> 1) & 0x7;
- b = (x >> 1) | (x << 6);
- c = 13;
- }
- break;
-
- case 159: {
- int x = (bits >> 1) & 0xF;
- b = (x >> 3) | (x << 5);
- c = 6;
- }
- break;
-
- default:
- assert(false && "Illegal quint encoding");
- break;
- }
-
- int t = quint * c + b;
- t ^= a;
- t = (a & 0x80) | (t >> 2);
- return t;
-}
-
-// Trit unquantization procedure as described in Section C.2.17. In the code
-// below, the variables a, b, and c correspond to the columns A, B, and C in
-// the specification.
-int GetUnquantizedTritWeight(int trit, int bits, int range) {
- int a = (bits & 1) ? 0x7F : 0;
- int b = 0, c = 0;
- switch (range) {
- case 2:
- return (std::array<int, 3> {{ 0, 32, 63 }})[trit];
-
- case 5:
- c = 50;
- b = 0;
- break;
-
- case 11: {
- c = 23;
- b = (bits >> 1) & 1;
- b |= (b << 2) | (b << 6);
- }
- break;
-
- case 23: {
- c = 11;
- b = (bits >> 1) & 0x3;
- b |= (b << 5);
- }
- break;
-
- default:
- assert(false && "Illegal trit encoding");
- break;
- }
-
- int t = trit * c + b;
- t ^= a;
- t = (a & 0x20) | (t >> 2);
- return t;
-}
-
-// Quint unquantization procedure as described in Section C.2.17. In the code
-// below, the variables a, b, and c correspond to the columns A, B, and C in
-// the specification.
-int GetUnquantizedQuintWeight(int quint, int bits, int range) {
- int a = (bits & 1) ? 0x7F : 0;
- int b = 0, c = 0;
- switch (range) {
- case 4:
- return (std::array<int, 5> {{ 0, 16, 32, 47, 63 }})[quint];
-
- case 9:
- c = 28;
- b = 0;
- break;
-
- case 19: {
- c = 13;
- b = (bits >> 1) & 0x1;
- b = (b << 1) | (b << 6);
- }
- break;
-
- default:
- assert(false && "Illegal quint encoding");
- break;
- }
-
- int t = quint * c + b;
- t ^= a;
- t = (a & 0x20) | (t >> 2);
- return t;
-}
-
-// A Quantization map allows us to convert to/from values that are quantized
-// according to the ASTC spec.
-class QuantizationMap {
- public:
- int Quantize(int x) const {
- return x < quantization_map_.size() ? quantization_map_.at(x) : 0;
- }
-
- int Unquantize(int x) const {
- return x < unquantization_map_.size() ? unquantization_map_.at(x) : 0;
- }
-
- protected:
- QuantizationMap() { }
- std::vector<int> quantization_map_;
- std::vector<int> unquantization_map_;
-
- void GenerateQuantizationMap() {
- assert(unquantization_map_.size() > 1);
- quantization_map_.clear();
-
- // TODO(google) For weights, we don't need quantization values all the
- // way up to 256, but it doesn't hurt -- just wastes memory, but the code
- // is much cleaner this way
- for (int i = 0; i < 256; ++i) {
- int best_idx = 0;
- int best_idx_score = 256;
- int idx = 0;
- for (int unquantized_val : unquantization_map_) {
- const int diff = i - unquantized_val;
- const int idx_score = diff * diff;
- if (idx_score < best_idx_score) {
- best_idx = idx;
- best_idx_score = idx_score;
- }
- idx++;
- }
-
- quantization_map_.push_back(best_idx);
- }
- }
-};
-
-template<int (*UnquantizationFunc)(int, int, int)>
-class TritQuantizationMap : public QuantizationMap {
- public:
- explicit TritQuantizationMap(int range) : QuantizationMap() {
- assert((range + 1) % 3 == 0);
- const int num_bits_pow_2 = (range + 1) / 3;
- const int num_bits =
- num_bits_pow_2 == 0 ? 0 : base::Log2Floor(num_bits_pow_2);
-
- for (int trit = 0; trit < 3; ++trit) {
- for (int bits = 0; bits < (1 << num_bits); ++bits) {
- unquantization_map_.push_back(UnquantizationFunc(trit, bits, range));
- }
- }
-
- GenerateQuantizationMap();
- }
-};
-
-template<int (*UnquantizationFunc)(int, int, int)>
-class QuintQuantizationMap : public QuantizationMap {
- public:
- explicit QuintQuantizationMap(int range) : QuantizationMap() {
- assert((range + 1) % 5 == 0);
- const int num_bits_pow_2 = (range + 1) / 5;
- const int num_bits =
- num_bits_pow_2 == 0 ? 0 : base::Log2Floor(num_bits_pow_2);
-
- for (int quint = 0; quint < 5; ++quint) {
- for (int bits = 0; bits < (1 << num_bits); ++bits) {
- unquantization_map_.push_back(UnquantizationFunc(quint, bits, range));
- }
- }
-
- GenerateQuantizationMap();
- }
-};
-
-template<int TotalUnquantizedBits>
-class BitQuantizationMap : public QuantizationMap {
- public:
- explicit BitQuantizationMap<TotalUnquantizedBits>(int range)
- : QuantizationMap() {
- // Make sure that if we're using bits then we have a positive power of two.
- assert(base::CountOnes(range + 1) == 1);
-
- const int num_bits = base::Log2Floor(range + 1);
- for (int bits = 0; bits <= range; ++bits) {
- // Need to replicate bits until we fill up the bits
- int unquantized = bits;
- int num_unquantized_bits = num_bits;
- while (num_unquantized_bits < TotalUnquantizedBits) {
- const int num_dst_bits_to_shift_up =
- std::min(num_bits, TotalUnquantizedBits - num_unquantized_bits);
- const int num_src_bits_to_shift_down =
- num_bits - num_dst_bits_to_shift_up;
- unquantized <<= num_dst_bits_to_shift_up;
- unquantized |= bits >> num_src_bits_to_shift_down;
- num_unquantized_bits += num_dst_bits_to_shift_up;
- }
- assert(num_unquantized_bits == TotalUnquantizedBits);
-
- unquantization_map_.push_back(unquantized);
-
- // Fill half of the quantization map with the previous value for bits
- // and the other half with the current value for bits
- if (bits > 0) {
- const int prev_unquant = unquantization_map_.at(bits - 1);
- while (quantization_map_.size() <= (prev_unquant + unquantized) / 2) {
- quantization_map_.push_back(bits - 1);
- }
- }
- while (quantization_map_.size() <= unquantized) {
- quantization_map_.push_back(bits);
- }
- }
-
- assert(quantization_map_.size() == 1 << TotalUnquantizedBits);
- }
-};
-
-using QMap = std::shared_ptr<QuantizationMap>;
-
-// Returns the quantization map for quantizing color values in [0, 255] with the
-// smallest range that can accommodate |r|
-static const QuantizationMap* GetQuantMapForValueRange(int r) {
- // Endpoint values can be quantized using bits, trits, or quints. Here we
- // store the quantization maps for each of the ranges that are supported by
- // such an encoding. That way we can choose the proper quantization procedure
- // based on the range of values rather than by having complicated switches and
- // logic. We must use a std::map here instead of a std::unordered_map because
- // of the assumption made in std::upper_bound about the iterators being from a
- // poset.
- static const auto* const kASTCEndpointQuantization = new std::map<int, QMap> {
- { 5, QMap(new TritQuantizationMap<GetUnquantizedTritValue>(5)) },
- { 7, QMap(new BitQuantizationMap<8>(7)) },
- { 9, QMap(new QuintQuantizationMap<GetUnquantizedQuintValue>(9)) },
- { 11, QMap(new TritQuantizationMap<GetUnquantizedTritValue>(11)) },
- { 15, QMap(new BitQuantizationMap<8>(15)) },
- { 19, QMap(new QuintQuantizationMap<GetUnquantizedQuintValue>(19)) },
- { 23, QMap(new TritQuantizationMap<GetUnquantizedTritValue>(23)) },
- { 31, QMap(new BitQuantizationMap<8>(31)) },
- { 39, QMap(new QuintQuantizationMap<GetUnquantizedQuintValue>(39)) },
- { 47, QMap(new TritQuantizationMap<GetUnquantizedTritValue>(47)) },
- { 63, QMap(new BitQuantizationMap<8>(63)) },
- { 79, QMap(new QuintQuantizationMap<GetUnquantizedQuintValue>(79)) },
- { 95, QMap(new TritQuantizationMap<GetUnquantizedTritValue>(95)) },
- { 127, QMap(new BitQuantizationMap<8>(127)) },
- { 159, QMap(new QuintQuantizationMap<GetUnquantizedQuintValue>(159)) },
- { 191, QMap(new TritQuantizationMap<GetUnquantizedTritValue>(191)) },
- { 255, QMap(new BitQuantizationMap<8>(255)) },
- };
-
- assert(r < 256);
- auto itr = kASTCEndpointQuantization->upper_bound(r);
- if (itr != kASTCEndpointQuantization->begin()) {
- return (--itr)->second.get();
- }
- return nullptr;
-}
-
-// Returns the quantization map for weight values in [0, 63] with the smallest
-// range that can accommodate |r|
-static const QuantizationMap* GetQuantMapForWeightRange(int r) {
- // Similar to endpoint quantization, weights can also be stored using trits,
- // quints, or bits. Here we store the quantization maps for each of the ranges
- // that are supported by such an encoding.
- static const auto* const kASTCWeightQuantization = new std::map<int, QMap> {
- { 1, QMap(new BitQuantizationMap<6>(1)) },
- { 2, QMap(new TritQuantizationMap<GetUnquantizedTritWeight>(2)) },
- { 3, QMap(new BitQuantizationMap<6>(3)) },
- { 4, QMap(new QuintQuantizationMap<GetUnquantizedQuintWeight>(4)) },
- { 5, QMap(new TritQuantizationMap<GetUnquantizedTritWeight>(5)) },
- { 7, QMap(new BitQuantizationMap<6>(7)) },
- { 9, QMap(new QuintQuantizationMap<GetUnquantizedQuintWeight>(9)) },
- { 11, QMap(new TritQuantizationMap<GetUnquantizedTritWeight>(11)) },
- { 15, QMap(new BitQuantizationMap<6>(15)) },
- { 19, QMap(new QuintQuantizationMap<GetUnquantizedQuintWeight>(19)) },
- { 23, QMap(new TritQuantizationMap<GetUnquantizedTritWeight>(23)) },
- { 31, QMap(new BitQuantizationMap<6>(31)) },
- };
-
- assert(r < 32);
- auto itr = kASTCWeightQuantization->upper_bound(r);
- if (itr != kASTCWeightQuantization->begin()) {
- return (--itr)->second.get();
- }
- return nullptr;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-int QuantizeCEValueToRange(int value, int range_max_value) {
- assert(range_max_value >= kEndpointRangeMinValue);
- assert(range_max_value <= 255);
- assert(value >= 0);
- assert(value <= 255);
-
- const QuantizationMap* map = GetQuantMapForValueRange(range_max_value);
- return map ? map->Quantize(value) : 0;
-}
-
-int UnquantizeCEValueFromRange(int value, int range_max_value) {
- assert(range_max_value >= kEndpointRangeMinValue);
- assert(range_max_value <= 255);
- assert(value >= 0);
- assert(value <= range_max_value);
-
- const QuantizationMap* map = GetQuantMapForValueRange(range_max_value);
- return map ? map->Unquantize(value) : 0;
-}
-
-int QuantizeWeightToRange(int weight, int range_max_value) {
- assert(range_max_value >= 1);
- assert(range_max_value <= kWeightRangeMaxValue);
- assert(weight >= 0);
- assert(weight <= 64);
-
- // The quantization maps that define weight unquantization expect values in
- // the range [0, 64), but the specification quantizes them to the range
- // [0, 64] according to C.2.17. This is a slight hack similar to the one in
- // the unquantization procedure to return the passed in unquantized value to
- // [0, 64) prior to running it through the quantization procedure.
- if (weight > 33) {
- weight -= 1;
- }
- const QuantizationMap* map = GetQuantMapForWeightRange(range_max_value);
- return map ? map->Quantize(weight) : 0;
-}
-
-int UnquantizeWeightFromRange(int weight, int range_max_value) {
- assert(range_max_value >= 1);
- assert(range_max_value <= kWeightRangeMaxValue);
- assert(weight >= 0);
- assert(weight <= range_max_value);
- const QuantizationMap* map = GetQuantMapForWeightRange(range_max_value);
- int dq = map ? map->Unquantize(weight) : 0;
-
- // Quantized weights are returned in the range [0, 64), but they should be
- // returned in the range [0, 64], so according to C.2.17 we need to add one
- // to the result.
- assert(dq < 64);
- if (dq > 32) {
- dq += 1;
- }
- return dq;
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/quantization.h b/third-party/astc-codec/src/decoder/quantization.h
deleted file mode 100644
index 5f7239f1..00000000
--- a/third-party/astc-codec/src/decoder/quantization.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_QUANTIZATION_H_
-#define ASTC_CODEC_DECODER_QUANTIZATION_H_
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// ASTC Quantization procedures.
-//
-// The values stored in ASTC blocks tend to be stored in a range much more
-// restricted than the logical range used. For example, sometimes weights are
-// stored in the range from [0, 3] but are used in the range [0, 64]. The
-// process of translating a value to or from this range is known as quantization
-// and dequantization. The ranges to which these values can be (de)quantized
-// are defined by ISERange[Begin|End]() in integer_sequence_codec.h
-
-namespace astc_codec {
-
-// The minimum possible range for a pair of endpoints. If endpoints are
-// quantized to something smaller than this, then it would constitute an
-// illegal ASTC encoding.
-constexpr int kEndpointRangeMinValue = 5;
-
-// The maximum possible range for a weight value. If weights are quantized to
-// something larger than this, then it would constitute an illegal ASTC
-// encoding.
-constexpr int kWeightRangeMaxValue = 31;
-
-// Quantizes a value in the range [0, 255] to [0, |range|]. The quantized values
-// have no correlation to the input values, and there should be no implicit
-// assumptions made about their ordering. Valid values of |range_max_value| are
-// in the interval [5, 255]
-int QuantizeCEValueToRange(int value, int range_max_value);
-
-// Unquantizes a value in the range [0, |range|] to [0, 255]. Performs the
-// inverse procedure of QuantizeValueToRange. Valid values of |range_max_value|
-// are in the interval [5, 255]
-int UnquantizeCEValueFromRange(int value, int range_max_value);
-
-// Quantizes a weight in the range [0, 64] to [0, |range_max_value|]. The
-// quantized values have no correlation to the input values, and there should
-// be no implicit assumptions made about their ordering. Valid values of
-// |range_max_value| are in the interval [1, 31]
-int QuantizeWeightToRange(int weight, int range_max_value);
-
-// Unquantizes a weight in the range [0, |range_max_value|] to [0, 64]. Performs
-// the inverse procedure of QuantizeWeightToRange. Valid values of
-// |range_max_value| are in the interval [1, 31]
-int UnquantizeWeightFromRange(int weight, int range_max_value);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_QUANTIZATION_H_
diff --git a/third-party/astc-codec/src/decoder/test/astc_fuzzer.cc b/third-party/astc-codec/src/decoder/test/astc_fuzzer.cc
deleted file mode 100644
index f152675d..00000000
--- a/third-party/astc-codec/src/decoder/test/astc_fuzzer.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// ASTC fuzzing wrapper to help with fuzz testing.
-
-#include "src/decoder/codec.h"
-
-#include <benchmark/benchmark.h>
-
-#include <vector>
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- std::string error;
- std::unique_ptr<astc_codec::ASTCFile> file =
- astc_codec::ASTCFile::LoadFromMemory(reinterpret_cast<const char*>(data),
- size, &error);
- if (file) {
- std::vector<uint8_t> out_buffer(file->GetWidth() * file->GetHeight() * 4);
- bool result = astc_codec::DecompressToImage(
- *file, out_buffer.data(), out_buffer.size(), file->GetWidth() * 4);
- benchmark::DoNotOptimize(result);
- }
-
- return 0;
-}
diff --git a/third-party/astc-codec/src/decoder/test/codec_test.cc b/third-party/astc-codec/src/decoder/test/codec_test.cc
deleted file mode 100644
index 936eed3e..00000000
--- a/third-party/astc-codec/src/decoder/test/codec_test.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/codec.h"
-#include "include/astc-codec/astc-codec.h"
-#include "src/decoder/test/image_utils.h"
-
-#include <gtest/gtest.h>
-
-#include <string>
-
-namespace astc_codec {
-
-static void PrintTo(FootprintType footprint, std::ostream* os) {
- switch (footprint) {
- case FootprintType::k4x4: *os << "FootprintType::k4x4"; break;
- case FootprintType::k5x4: *os << "FootprintType::k5x4"; break;
- case FootprintType::k5x5: *os << "FootprintType::k5x5"; break;
- case FootprintType::k6x5: *os << "FootprintType::k6x5"; break;
- case FootprintType::k6x6: *os << "FootprintType::k6x6"; break;
- case FootprintType::k8x5: *os << "FootprintType::k8x5"; break;
- case FootprintType::k8x6: *os << "FootprintType::k8x6"; break;
- case FootprintType::k10x5: *os << "FootprintType::k10x5"; break;
- case FootprintType::k10x6: *os << "FootprintType::k10x6"; break;
- case FootprintType::k8x8: *os << "FootprintType::k8x8"; break;
- case FootprintType::k10x8: *os << "FootprintType::k10x8"; break;
- case FootprintType::k10x10: *os << "FootprintType::k10x10"; break;
- case FootprintType::k12x10: *os << "FootprintType::k12x10"; break;
- case FootprintType::k12x12: *os << "FootprintType::k12x12"; break;
- default:
- *os << "<Unexpected FootprintType "
- << static_cast<uint32_t>(footprint) << ">";
- }
-}
-
-namespace {
-
-using ::testing::TestWithParam;
-using ::testing::ValuesIn;
-
-ImageBuffer LoadGoldenImageWithAlpha(std::string basename) {
- const std::string filename =
- std::string("src/decoder/testdata/") + basename + ".bmp";
- ImageBuffer result;
- LoadGoldenBmp(filename, &result);
- EXPECT_EQ(result.BytesPerPixel(), 4);
- return result;
-}
-
-struct ImageTestParams {
- std::string image_name;
- FootprintType footprint;
- size_t width;
- size_t height;
-};
-
-static void PrintTo(const ImageTestParams& params, std::ostream* os) {
- *os << "ImageTestParams(" << params.image_name << ", " << params.width << "x"
- << params.height << ", ";
- PrintTo(params.footprint, os);
- *os << ")";
-}
-
-TEST(CodecTest, InvalidInput) {
- const size_t valid_width = 16;
- const size_t valid_height = 16;
- const size_t valid_stride = valid_width * 4;
-
- const std::vector<uint8_t> data(256);
- std::vector<uint8_t> output(valid_width * valid_height * 4);
-
- // Invalid footprint.
- EXPECT_FALSE(ASTCDecompressToRGBA(
- data.data(), data.size(), valid_width, valid_height,
- FootprintType::kCount, output.data(), output.size(), valid_stride));
-
- // Fail for 0 width or height.
- EXPECT_FALSE(ASTCDecompressToRGBA(data.data(), data.size(), 0, valid_height,
- FootprintType::k4x4, output.data(),
- output.size(), valid_stride));
- EXPECT_FALSE(ASTCDecompressToRGBA(data.data(), data.size(), valid_width, 0,
- FootprintType::k4x4, output.data(),
- output.size(), valid_stride));
-
- // Fail for data size that's not a multiple of block size.
- EXPECT_FALSE(ASTCDecompressToRGBA(
- data.data(), data.size() - 1, valid_width, valid_height,
- FootprintType::k4x4, output.data(), output.size(), valid_stride));
- // Fail for data size that doesn't match the block count.
- EXPECT_FALSE(ASTCDecompressToRGBA(
- data.data(), data.size() - 16, valid_width, valid_height,
- FootprintType::k4x4, output.data(), output.size(), valid_stride));
-
- // Fail for invalid stride.
- EXPECT_FALSE(ASTCDecompressToRGBA(
- data.data(), data.size(), valid_width, valid_height, FootprintType::k4x4,
- output.data(), output.size(), valid_stride - 1));
-
- // Fail for invalid output size.
- EXPECT_FALSE(ASTCDecompressToRGBA(
- data.data(), data.size(), valid_width, valid_height, FootprintType::k4x4,
- output.data(), output.size() - 1, valid_stride));
-}
-
-class CodecTest : public TestWithParam<ImageTestParams> {};
-
-TEST_P(CodecTest, PublicAPI) {
- const auto& params = GetParam();
- const std::string astc = LoadASTCFile(params.image_name);
-
- ImageBuffer our_decoded_image;
- our_decoded_image.Allocate(params.width, params.height, 4);
- ASSERT_TRUE(ASTCDecompressToRGBA(
- reinterpret_cast<const uint8_t*>(astc.data()), astc.size(), params.width,
- params.height, params.footprint, our_decoded_image.Data().data(),
- our_decoded_image.DataSize(), our_decoded_image.Stride()));
-
- // Check that the decoded image is *very* similar to the library decoding
- // of an ASTC texture. They may not be exact due to differences in how we
- // convert a 16-bit float to an 8-bit integer.
- ImageBuffer decoded_image = LoadGoldenImageWithAlpha(params.image_name);
- CompareSumOfSquaredDifferences(decoded_image, our_decoded_image, 1.0);
-}
-
-TEST_P(CodecTest, DecompressToImage) {
- const auto& params = GetParam();
-
- std::string error;
- std::unique_ptr<ASTCFile> image_file = ASTCFile::LoadFile(
- std::string("src/decoder/testdata/") + params.image_name + ".astc",
- &error);
- ASSERT_TRUE(image_file) << "Failed to load " << params.image_name << ": "
- << error;
-
- ASSERT_TRUE(image_file->GetFootprint());
- EXPECT_EQ(params.footprint, image_file->GetFootprint().value().Type());
-
- ImageBuffer our_decoded_image;
- our_decoded_image.Allocate(image_file->GetWidth(), image_file->GetHeight(),
- 4);
-
- ASSERT_TRUE(DecompressToImage(*image_file, our_decoded_image.Data().data(),
- our_decoded_image.DataSize(),
- our_decoded_image.Stride()));
-
- // Check that the decoded image is *very* similar to the library decoding
- // of an ASTC texture. They may not be exact due to differences in how we
- // convert a 16-bit float to an 8-bit integer.
- ImageBuffer decoded_image = LoadGoldenImageWithAlpha(params.image_name);
- CompareSumOfSquaredDifferences(decoded_image, our_decoded_image, 1.0);
-}
-
-// Test to make sure that reading out color values from blocks in a real-world
-// image isn't terribly wrong, either.
-std::vector<ImageTestParams> GetTransparentImageTestParams() {
- return {
- // image_name astc footprint width height
- { "atlas_small_4x4", FootprintType::k4x4, 256, 256 },
- { "atlas_small_5x5", FootprintType::k5x5, 256, 256 },
- { "atlas_small_6x6", FootprintType::k6x6, 256, 256 },
- { "atlas_small_8x8", FootprintType::k8x8, 256, 256 },
- };
-}
-
-INSTANTIATE_TEST_CASE_P(Transparent, CodecTest,
- ValuesIn(GetTransparentImageTestParams()));
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/test/endpoint_codec_test.cc b/third-party/astc-codec/src/decoder/test/endpoint_codec_test.cc
deleted file mode 100644
index de7d9cab..00000000
--- a/third-party/astc-codec/src/decoder/test/endpoint_codec_test.cc
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/endpoint_codec.h"
-#include "src/decoder/intermediate_astc_block.h"
-#include "src/decoder/test/image_utils.h"
-
-#include <random>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-namespace astc_codec {
-
-namespace {
-
-using ::testing::AllOf;
-using ::testing::AnyOf;
-using ::testing::Each;
-using ::testing::Eq;
-using ::testing::Ge;
-using ::testing::Le;
-using ::testing::Ne;
-using ::testing::Pointwise;
-using ::testing::SizeIs;
-using ::testing::Pair;
-
-constexpr std::array<EndpointEncodingMode, 6> kEndpointEncodingModes = {{
- EndpointEncodingMode::kDirectLuma,
- EndpointEncodingMode::kDirectLumaAlpha,
- EndpointEncodingMode::kBaseScaleRGB,
- EndpointEncodingMode::kBaseScaleRGBA,
- EndpointEncodingMode::kDirectRGB,
- EndpointEncodingMode::kDirectRGBA }};
-
-const std::array<std::pair<RgbaColor, RgbaColor>, 3> kBlueContractPairs = {{
- std::make_pair(RgbaColor{{ 22, 18, 30, 59 }},
- RgbaColor{{ 162, 148, 155, 59 }}),
- std::make_pair(RgbaColor{{ 22, 30, 27, 36 }},
- RgbaColor{{ 228, 221, 207, 36 }}),
- std::make_pair(RgbaColor{{ 54, 60, 55, 255 }},
- RgbaColor{{ 23, 30, 27, 255 }})
- }};
-
-// Used to directly initialize std::pairs of colors with initializer lists
-// e.g. MakeColors({{ r, g, b, a }}, {{ r, g, b, a }});
-std::pair<RgbaColor, RgbaColor> MakeColors(RgbaColor&& a, RgbaColor&& b) {
- return std::make_pair(a, b);
-}
-
-// Returns |high| and |low| as they would be decoded using the quantization
-// factor |quant| for the ColorEndpointMode |mode|.
-std::pair<RgbaColor, RgbaColor> TestColors(
- RgbaColor low, RgbaColor high, int quant, EndpointEncodingMode mode) {
- ColorEndpointMode astc_mode;
- std::vector<int> encoded;
- const bool needs_swap =
- EncodeColorsForMode(low, high, quant, mode, &astc_mode, &encoded);
-
- RgbaColor decoded_low, decoded_high;
- DecodeColorsForMode(encoded, quant, astc_mode, &decoded_low, &decoded_high);
-
- if (needs_swap) {
- return std::make_pair(decoded_high, decoded_low);
- } else {
- return std::make_pair(decoded_low, decoded_high);
- }
-}
-
-// Returns true if the argument tuple entries only differ by at most x.
-MATCHER_P(IsCloseTo, x, "") {
- const auto& a = ::testing::get<0>(arg);
- const auto& b = ::testing::get<1>(arg);
- return (a > b) ? ((a - b) <= x) : ((b - a) <= x);
-}
-
-// Test to make sure that the range of values that we get as they are
-// quantized remains within what we pass as |quant|.
-TEST(EndpointCodecTest, QuantRanges) {
- const RgbaColor low {{ 0, 0, 0, 0 }};
- const RgbaColor high {{ 255, 255, 255, 255 }};
-
- std::vector<int> result;
- for (const auto& mode : kEndpointEncodingModes) {
- for (int i = 5; i < 256; ++i) {
- ColorEndpointMode astc_mode;
- const bool needs_swap =
- EncodeColorsForMode(low, high, i, mode, &astc_mode, &result);
- EXPECT_EQ(result.size(), NumValuesForEncodingMode(mode)) << i;
- EXPECT_EQ(result.size(), NumColorValuesForEndpointMode(astc_mode)) << i;
-
- // ASTC mode shouldn't use base/offset when endpoints are so far apart.
- EXPECT_THAT(astc_mode, Ne(ColorEndpointMode::kLDRRGBBaseOffset));
- EXPECT_THAT(astc_mode, Ne(ColorEndpointMode::kLDRRGBABaseOffset));
-
- EXPECT_THAT(result, Each(AllOf(Ge(0), Le(i))))
- << "Mode: " << static_cast<int>(mode);
- // We don't care if we need to swap the weights in this test
- EXPECT_TRUE(needs_swap || !needs_swap);
- }
- }
-}
-
-// Test to make sure that each mode that directly encodes colors can effectively
-// encode both black and white
-TEST(EndpointCodecTest, ExtremeDirectEncodings) {
- const RgbaColor kWhite {{ 255, 255, 255, 255 }};
- const RgbaColor kBlack {{ 0, 0, 0, 255 }};
-
- std::vector<int> encoded;
- for (const auto& mode : kEndpointEncodingModes) {
- for (int i = 5; i < 256; ++i) {
- const auto expected = std::make_pair(kWhite, kBlack);
- EXPECT_EQ(TestColors(kWhite, kBlack, i, mode), expected)
- << "Range: " << i << ", Mode: " << static_cast<int>(mode);
- }
- }
-}
-
-// According to the spec, this is used for colors close to gray. The values
-// chosen here were according to the spec.
-TEST(EndpointCodecTest, UsesBlueContract) {
- std::vector<int> vals = { 132, 127, 116, 112, 183, 180, 31, 22 };
- EXPECT_TRUE(UsesBlueContract(255, ColorEndpointMode::kLDRRGBDirect, vals));
- EXPECT_TRUE(UsesBlueContract(255, ColorEndpointMode::kLDRRGBADirect, vals));
-
- // For the offset modes the only way to trigger the blue contract mode is if
- // we force the subtraction in the decoding procedure (See section C.2.14 of
- // the spec), so we need to set the 7th bit to 1 for all of the odd-numbered
- // values
- vals[1] &= 0xBF;
- vals[3] &= 0xBF;
- vals[5] &= 0xBF;
- vals[7] &= 0xBF;
-
- EXPECT_FALSE(
- UsesBlueContract(255, ColorEndpointMode::kLDRRGBBaseOffset, vals));
- EXPECT_FALSE(
- UsesBlueContract(255, ColorEndpointMode::kLDRRGBABaseOffset, vals));
-
- vals[1] |= 0x40;
- vals[3] |= 0x40;
- vals[5] |= 0x40;
- vals[7] |= 0x40;
-
- EXPECT_TRUE(
- UsesBlueContract(255, ColorEndpointMode::kLDRRGBBaseOffset, vals));
- EXPECT_TRUE(
- UsesBlueContract(255, ColorEndpointMode::kLDRRGBABaseOffset, vals));
-
- // All other LDR endpoint modes should return no blue contract
- for (int max_val : { 255, 127, 11 }) {
- for (auto mode : { ColorEndpointMode::kLDRLumaDirect,
- ColorEndpointMode::kLDRLumaBaseOffset,
- ColorEndpointMode::kLDRLumaAlphaDirect,
- ColorEndpointMode::kLDRLumaAlphaBaseOffset,
- ColorEndpointMode::kLDRRGBBaseScale,
- ColorEndpointMode::kLDRRGBBaseScaleTwoA }) {
- EXPECT_FALSE(UsesBlueContract(max_val, mode, vals));
- }
- }
-}
-
-// Make sure that encoding and decoding for the direct luminance mode works.
-TEST(EndpointCodecTest, LumaDirect) {
- const auto mode = EndpointEncodingMode::kDirectLuma;
-
- // With a 255 quantizer, all greys should be exact.
- for (int i = 0; i < 255; ++i) {
- for (int j = 0; j < 255; ++j) {
- EXPECT_EQ(TestColors({{ i, i, i, 255 }}, {{ j, j, j, 255 }}, 255, mode),
- MakeColors({{ i, i, i, 255 }}, {{ j, j, j, 255 }}));
- }
- }
-
- // If we have almost grey, then they should encode to grey.
- EXPECT_EQ(TestColors({{ 247, 248, 246, 255 }}, {{ 2, 3, 1, 255 }}, 255, mode),
- MakeColors({{ 247, 247, 247, 255 }}, {{ 2, 2, 2, 255 }}));
-
- EXPECT_EQ(TestColors({{ 80, 80, 50, 255 }}, {{ 99, 255, 6, 255 }}, 255, mode),
- MakeColors({{ 70, 70, 70, 255 }}, {{ 120, 120, 120, 255 }}));
-
- // If we have almost greys and a really small quantizer, it should be white
- // and black (literally).
- EXPECT_EQ(TestColors({{ 247, 248, 246, 255 }}, {{ 2, 3, 1, 255 }}, 15, mode),
- MakeColors({{ 255, 255, 255, 255 }}, {{ 0, 0, 0, 255 }}));
-
- // The average of 64, 127, and 192 is 127.666..., so it should round to
- // 130 instead of 125.
- EXPECT_EQ(TestColors({{ 64, 127, 192, 255 }}, {{ 0, 0, 0, 255 }}, 63, mode),
- MakeColors({{ 130, 130, 130, 255 }}, {{ 0, 0, 0, 255 }}));
-
- // If we have almost grey, then they should encode to grey -- similar to
- // direct encoding since the encoded colors differ by < 63.
- EXPECT_EQ(TestColors({{ 80, 80, 50, 255 }}, {{ 99, 255, 6, 255 }}, 255, mode),
- MakeColors({{ 70, 70, 70, 255 }}, {{ 120, 120, 120, 255 }}));
-
- // Low precision colors should still encode pretty well with base/offset.
- EXPECT_EQ(TestColors({{ 35, 36, 38, 255 }}, {{ 42, 43, 40, 255 }}, 47, mode),
- MakeColors({{ 38, 38, 38, 255 }}, {{ 43, 43, 43, 255 }}));
-
- EXPECT_EQ(TestColors({{ 39, 42, 40, 255 }}, {{ 18, 20, 21, 255 }}, 39, mode),
- MakeColors({{ 39, 39, 39, 255 }}, {{ 19, 19, 19, 255 }}));
-}
-
-// Test encoding and decoding for the base-offset luminance mode.
-TEST(EndpointCodecTest, LumaAlphaDirect) {
- const auto mode = EndpointEncodingMode::kDirectLumaAlpha;
-
- // With a 255 quantizer, all greys should be exact.
- for (int i = 0; i < 255; ++i) {
- for (int j = 0; j < 255; ++j) {
- EXPECT_EQ(TestColors({{ i, i, i, j }}, {{ j, j, j, i }}, 255, mode),
- MakeColors({{ i, i, i, j }}, {{ j, j, j, i }}));
- }
- }
-
- // If we have almost grey, then they should encode to grey.
- EXPECT_EQ(TestColors({{ 247, 248, 246, 250 }}, {{ 2, 3, 1, 172 }}, 255, mode),
- MakeColors({{ 247, 247, 247, 250 }}, {{ 2, 2, 2, 172 }}));
-
- EXPECT_EQ(TestColors({{ 80, 80, 50, 0 }}, {{ 99, 255, 6, 255 }}, 255, mode),
- MakeColors({{ 70, 70, 70, 0 }}, {{ 120, 120, 120, 255 }}));
-
- // If we have almost greys and a really small quantizer, it should be white
- // and black (literally).
- EXPECT_EQ(TestColors({{ 247, 248, 246, 253 }}, {{ 2, 3, 1, 3 }}, 15, mode),
- MakeColors({{ 255, 255, 255, 255 }}, {{ 0, 0, 0, 0 }}));
-
- // The average of 64, 127, and 192 is 127.666..., so it should round to
- // 130 instead of 125. The alpha in this case is independent.
- EXPECT_EQ(TestColors({{ 64, 127, 192, 127 }}, {{ 0, 0, 0, 20 }}, 63, mode),
- MakeColors({{ 130, 130, 130, 125 }}, {{ 0, 0, 0, 20 }}));
-}
-
-// Test encoding for the direct RGB mode.
-TEST(EndpointCodecTest, RGBDirect) {
- const auto mode = EndpointEncodingMode::kDirectRGB;
-
- // Colors should be encoded exactly with a 255 quantizer.
- std::mt19937 random(0xdeadbeef);
- std::uniform_int_distribution<int> byte_distribution(0, 255);
-
- for (int i = 0; i < 100; ++i) {
- RgbaColor low, high;
- for (auto& x : high) { x = byte_distribution(random); }
- for (auto& x : low) { x = byte_distribution(random); }
- high[3] = low[3] = 255; // RGB Direct mode has opaque alpha.
-
- EXPECT_EQ(TestColors(low, high, 255, mode), std::make_pair(low, high))
- << "Random iter: " << i;
- }
-
- // For each of the following tests, order of endpoints shouldn't have any
- // bearing on the quantization properties, so we should be able to switch
- // endpoints as we see fit and have them generate the same flipped encoded
- // pairs.
-
- EXPECT_EQ(TestColors({{ 64, 127, 192, 255 }}, {{ 0, 0, 0, 255 }}, 63, mode),
- MakeColors({{ 65, 125, 190, 255 }}, {{ 0, 0, 0, 255 }}));
-
- EXPECT_EQ(TestColors({{ 0, 0, 0, 255 }}, {{ 64, 127, 192, 255 }}, 63, mode),
- MakeColors({{ 0, 0, 0, 255 }}, {{ 65, 125, 190, 255 }}));
-
- EXPECT_EQ(TestColors({{ 1, 2, 94, 255 }}, {{ 168, 255, 13, 255 }}, 7, mode),
- MakeColors({{ 0, 0, 109, 255 }}, {{ 182, 255, 0, 255 }}));
-
- // Colors close to grey will likely need a blue contract.
- EXPECT_EQ(TestColors(kBlueContractPairs[0].first,
- kBlueContractPairs[0].second, 31, mode),
- MakeColors({{ 24, 20, 33, 255 }}, {{ 160, 148, 156, 255 }}));
-
- EXPECT_EQ(TestColors(kBlueContractPairs[0].second,
- kBlueContractPairs[0].first, 31, mode),
- MakeColors({{ 160, 148, 156, 255 }}, {{ 24, 20, 33, 255 }}));
-
- EXPECT_EQ(TestColors(kBlueContractPairs[1].first,
- kBlueContractPairs[1].second, 7, mode),
- MakeColors({{ 18, 36, 36, 255 }}, {{ 237, 219, 219, 255 }}));
-
- EXPECT_EQ(TestColors(kBlueContractPairs[1].second,
- kBlueContractPairs[1].first, 7, mode),
- MakeColors({{ 237, 219, 219, 255 }}, {{ 18, 36, 36, 255 }}));
-
- // Colors close to grey (and each other) will likely need a blue contract AND
- // use the offset mode for encoding
- EXPECT_EQ(TestColors(kBlueContractPairs[2].first,
- kBlueContractPairs[2].second, 31, mode),
- MakeColors({{ 53, 59, 53, 255 }}, {{ 24, 30, 26, 255 }}));
-
- EXPECT_EQ(TestColors(kBlueContractPairs[2].second,
- kBlueContractPairs[2].first, 31, mode),
- MakeColors({{ 24, 30, 26, 255 }}, {{ 53, 59, 53, 255 }}));
-
- // Colors close to each other, but not to grey will likely only use the offset
- // mode and not the blue-contract modes.
- EXPECT_EQ(TestColors({{ 22, 148, 30, 59 }}, {{ 162, 18, 155, 59 }}, 31, mode),
- MakeColors({{ 24, 148, 33, 255 }}, {{ 165, 16, 156, 255 }}));
-
- EXPECT_EQ(TestColors({{ 162, 18, 155, 59 }}, {{ 22, 148, 30, 59 }}, 31, mode),
- MakeColors({{ 165, 16, 156, 255 }}, {{ 24, 148, 33, 255 }}));
-}
-
-// Make sure that certain endpoint pairs result in the blue-contract path as
-// we'd expect, such that we can make sure that we're hitting all of the encode
-// paths.
-TEST(EndpointCodecTest, RGBDirectMakesBlueContract) {
- constexpr int kEndpointRange = 31;
- for (const auto& endpoint_pair : kBlueContractPairs) {
- ColorEndpointMode astc_mode;
- std::vector<int> vals;
- bool needs_swap = EncodeColorsForMode(
- endpoint_pair.first, endpoint_pair.second,
- kEndpointRange, EndpointEncodingMode::kDirectRGB, &astc_mode, &vals);
- (void)(needs_swap); // Don't really care.
-
- EXPECT_TRUE(UsesBlueContract(kEndpointRange, astc_mode, vals));
- }
-}
-
-// Make sure that encoding and decoding for the RGB base-scale mode works.
-TEST(EndpointCodecTest, RGBBaseScale) {
- const auto mode = EndpointEncodingMode::kBaseScaleRGB;
- const auto close_to = [](RgbaColor c, int x) {
- return Pointwise(IsCloseTo(x), c);
- };
-
- // Identical colors should be encoded with a 255 scale factor. Since ASTC
- // decodes the scaled color by doing (x * s) >> 8, the decoded color will be
- // multiplied by 255/256. This might cause rounding errors sometimes, so we
- // check that every channel only deviates by 1.
- std::mt19937 random(0xdeadbeef);
- std::uniform_int_distribution<int> byte_distribution(0, 255);
-
- for (int i = 0; i < 100; ++i) {
- RgbaColor color{{byte_distribution(random), byte_distribution(random),
- byte_distribution(random), 255}};
- const auto test_result = TestColors(color, color, 255, mode);
- EXPECT_THAT(test_result, Pair(close_to(color, 1), close_to(color, 1)));
- }
-
- // Make sure that if we want to scale by e.g. 1/4 then we can do that exactly:
- const RgbaColor low = {{ 20, 4, 40, 255 }};
- const RgbaColor high = {{ 80, 16, 160, 255 }};
- EXPECT_THAT(TestColors(low, high, 255, mode),
- Pair(close_to(low, 0), close_to(high, 0)));
-
- // And if we quantize it, then we get roughly the same thing. The scale factor
- // should be representable with most quantization levels. The problem is that
- // if we're off on the 'high' color, then we will be off on the 'low' color.
- EXPECT_THAT(TestColors(low, high, 127, mode),
- Pair(close_to(low, 1), close_to(high, 1)));
-
- EXPECT_THAT(TestColors(low, high, 63, mode),
- Pair(close_to(low, 1), close_to(high, 2)));
-
- EXPECT_THAT(TestColors(low, high, 31, mode),
- Pair(close_to(low, 1), close_to(high, 4)));
-
- EXPECT_THAT(TestColors(low, high, 15, mode),
- Pair(close_to(low, 2), close_to(high, 8)));
-}
-
-// Make sure that encoding and decoding for the RGB base-offset mode works.
-// Since we don't have a decoder, this is currently only a test that should work
-// based on reasoning about what's written in the spec.
-// TODO(krajcevski): Write an encoder.
-TEST(EndpointCodecTest, RGBBaseOffset) {
- const auto test_colors = [](const RgbaColor& low, const RgbaColor& high) {
- const RgbaColor diff = {{ high[0] - low[0], high[1] - low[1],
- high[2] - low[2], high[3] - low[3] }};
-
- std::vector<int> vals;
- for (int i = 0; i < 3; ++i) {
- // If the base is "large", then it grabs it's most significant bit from
- // the offset value. Hence, we need to save it here.
- const bool is_large = low[i] >= 128;
- vals.push_back((low[i] * 2) & 0xFF);
- vals.push_back(diff[i] * 2);
-
- // Give the "large" bases their bits back.
- if (is_large) {
- vals.back() |= 0x80;
- }
- }
-
- RgbaColor dec_low, dec_high;
- DecodeColorsForMode(vals, 255, ColorEndpointMode::kLDRRGBBaseOffset,
- &dec_low, &dec_high);
-
- EXPECT_THAT(std::make_pair(dec_low, dec_high), Pair(Eq(low), Eq(high)));
- };
-
- // Test the "direct encoding" path.
- test_colors({{ 80, 16, 112, 255 }}, {{ 87, 18, 132, 255 }});
- test_colors({{ 80, 74, 82, 255 }}, {{ 90, 92, 110, 255 }});
- test_colors({{ 0, 0, 0, 255 }}, {{ 2, 2, 2, 255 }});
-
- // Identical endpoints should always encode exactly, provided they satisfy the
- // requirements for the base encoding.
- std::mt19937 random(0xdeadbeef);
- std::uniform_int_distribution<int> byte_distribution(0, 255);
- for (int i = 0; i < 100; ++i) {
- RgbaColor color{{byte_distribution(random), byte_distribution(random),
- byte_distribution(random), 255}};
- if ((color[0] | color[1] | color[2]) & 1) {
- continue;
- }
- test_colors(color, color);
- }
-
- // TODO(google): Test the "blue contract" path.
-}
-
-// Make sure that we can decode colors that are given to us straight out of the
-// ASTC codec.
-TEST(EndpointCodecTest, DecodeCheckerboard) {
- const RgbaColor kWhite {{ 255, 255, 255, 255 }};
- const RgbaColor kBlack {{ 0, 0, 0, 255 }};
-
- const std::string astc = LoadASTCFile("checkerboard");
- for (int i = 0; i < astc.size(); i += 16) {
- base::UInt128 block;
- memcpy(&block, &astc[i], sizeof(block));
-
- const auto intermediate = UnpackIntermediateBlock(PhysicalASTCBlock(block));
- ASSERT_TRUE(intermediate) << "Block is void extent???";
-
- const auto block_data = &intermediate.value();
- ASSERT_THAT(block_data->endpoints, SizeIs(Eq(1)));
-
- const int color_range = EndpointRangeForBlock(*block_data);
- const auto& endpoints = block_data->endpoints[0];
-
- RgbaColor low, high;
- DecodeColorsForMode(endpoints.colors, color_range, endpoints.mode,
- &low, &high);
-
- // Expect that the endpoints are black and white, but either order.
- EXPECT_THAT(std::make_pair(low, high),
- AnyOf(
- Pair(Eq(kWhite), Eq(kBlack)),
- Pair(Eq(kBlack), Eq(kWhite))));
- }
-}
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/test/footprint_test.cc b/third-party/astc-codec/src/decoder/test/footprint_test.cc
deleted file mode 100644
index 6aef98a7..00000000
--- a/third-party/astc-codec/src/decoder/test/footprint_test.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/footprint.h"
-
-#include <array>
-#include <tuple>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-namespace astc_codec {
-
-namespace {
-
-TEST(FootprintTest, ParseAstcFootprintString) {
- using ASTCTestPair = std::pair<std::string, Footprint>;
- const std::array<ASTCTestPair, Footprint::NumValidFootprints()>
- valid_footprints {{
- std::make_pair("4x4", Footprint::Get4x4()),
- std::make_pair("5x4", Footprint::Get5x4()),
- std::make_pair("5x5", Footprint::Get5x5()),
- std::make_pair("6x5", Footprint::Get6x5()),
- std::make_pair("6x6", Footprint::Get6x6()),
- std::make_pair("8x5", Footprint::Get8x5()),
- std::make_pair("8x6", Footprint::Get8x6()),
- std::make_pair("8x8", Footprint::Get8x8()),
- std::make_pair("10x5", Footprint::Get10x5()),
- std::make_pair("10x6", Footprint::Get10x6()),
- std::make_pair("10x8", Footprint::Get10x8()),
- std::make_pair("10x10", Footprint::Get10x10()),
- std::make_pair("12x10", Footprint::Get12x10()),
- std::make_pair("12x12", Footprint::Get12x12())
- }};
-
- for (const auto& test : valid_footprints) {
- base::Optional<Footprint> footprint = Footprint::Parse(test.first.c_str());
- EXPECT_TRUE(footprint);
- EXPECT_EQ(test.second, footprint.value());
- }
-
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(Footprint::Parse("")), "");
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(Footprint::Parse("3")), "");
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(Footprint::Parse("x")), "");
- // Validly formed but out-of-bounds dimensions do not assert, otherwise
- // malformed ASTC files could crash the decoder in debug builds.
- EXPECT_FALSE(Footprint::Parse("9999999999x10"));
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(Footprint::Parse("ax8")), "");
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(Footprint::Parse("2x3x4")), "");
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(Footprint::Parse("-3x4")), "");
- EXPECT_FALSE(Footprint::Parse("10x4"));
-}
-
-TEST(FootprintTest, Bitrates) {
- EXPECT_NEAR(Footprint::Get4x4().Bitrate(), 8.f, 0.01f);
- EXPECT_NEAR(Footprint::Get5x4().Bitrate(), 6.4f, 0.01f);
- EXPECT_NEAR(Footprint::Get5x5().Bitrate(), 5.12f, 0.01f);
- EXPECT_NEAR(Footprint::Get6x5().Bitrate(), 4.27f, 0.01f);
- EXPECT_NEAR(Footprint::Get6x6().Bitrate(), 3.56f, 0.01f);
- EXPECT_NEAR(Footprint::Get8x5().Bitrate(), 3.20f, 0.01f);
- EXPECT_NEAR(Footprint::Get8x6().Bitrate(), 2.67f, 0.01f);
- EXPECT_NEAR(Footprint::Get8x8().Bitrate(), 2.00f, 0.01f);
- EXPECT_NEAR(Footprint::Get10x5().Bitrate(), 2.56f, 0.01f);
- EXPECT_NEAR(Footprint::Get10x6().Bitrate(), 2.13f, 0.01f);
- EXPECT_NEAR(Footprint::Get10x8().Bitrate(), 1.60f, 0.01f);
- EXPECT_NEAR(Footprint::Get10x10().Bitrate(), 1.28f, 0.01f);
- EXPECT_NEAR(Footprint::Get12x10().Bitrate(), 1.07f, 0.01f);
- EXPECT_NEAR(Footprint::Get12x12().Bitrate(), 0.89f, 0.01f);
-}
-
-TEST(FootprintTest, StorageRequirements) {
- auto footprint = Footprint::Get10x8();
- EXPECT_EQ(footprint.Width(), 10);
- EXPECT_EQ(footprint.Height(), 8);
-
- // If we have 8x8 blocks, then we have 64*16 = 1024 bytes.
- EXPECT_EQ(footprint.StorageRequirements(80, 64), 1024);
-
- // If our block is a little smaller this still counts because we need to
- // cover a partial block with a fully encoded one.
- EXPECT_EQ(footprint.StorageRequirements(79, 63), 1024);
-}
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/test/image_utils.h b/third-party/astc-codec/src/decoder/test/image_utils.h
deleted file mode 100644
index 1e5000a3..00000000
--- a/third-party/astc-codec/src/decoder/test/image_utils.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <fstream>
-#include <vector>
-
-static constexpr size_t kMaxVectorOutput = 128;
-
-class ImageBuffer {
- public:
- static constexpr size_t Align = 4;
-
- void Allocate(size_t width, size_t height, size_t bytes_per_pixel) {
- width_ = width;
- height_ = height;
- bytes_per_pixel_ = bytes_per_pixel;
- stride_ = AlignBytes(width * bytes_per_pixel);
- data_.resize(stride_ * height);
- }
-
- uint8_t* operator()(size_t x, size_t y) {
- assert(x < width_ && y < height_);
- return &data_[y * Stride() + x * bytes_per_pixel_];
- }
-
- size_t Stride() const { return stride_; }
- size_t BytesPerPixel() const { return bytes_per_pixel_; }
-
- std::vector<uint8_t>& Data() { return data_; }
- const std::vector<uint8_t>& Data() const { return data_; }
- size_t DataSize() const { return data_.size(); }
-
- private:
- size_t AlignBytes(size_t bytes) const {
- return (bytes + (Align - 1)) / Align * Align;
- }
-
- size_t width_ = 0;
- size_t height_ = 0;
- size_t stride_ = 0;
- size_t bytes_per_pixel_ = 0;
- std::vector<uint8_t> data_;
-};
-
-namespace std {
-static void PrintTo(const vector<uint8_t>& vec, ostream* os) {
- ios::fmtflags origFlags(os->flags());
-
- *os << '{';
- size_t count = 0;
- for (vector<uint8_t>::const_iterator it = vec.begin(); it != vec.end();
- ++it, ++count) {
- if (count > 0) {
- *os << ", ";
- }
-
- if (count == kMaxVectorOutput) {
- *os << "... ";
- break;
- }
-
- if ((count % 16) == 0) {
- *os << "\n";
- }
-
- if (*it == 0) {
- *os << " ";
- } else {
- *os << "0x" << std::hex << std::uppercase << std::setw(2)
- << std::setfill('0') << int(*it) << std::dec;
- }
- }
-
- *os << '}';
-
- os->flags(origFlags);
-}
-} // namespace std
-
-static inline std::string LoadFile(const std::string& path) {
- std::ifstream is(path, std::ios::binary);
- EXPECT_TRUE(is) << "Failed to load file " << path;
- if (!is) {
- return "";
- }
-
- std::ostringstream ss;
- ss << is.rdbuf();
- return ss.str();
-}
-
-static inline std::string LoadASTCFile(const std::string& basename) {
- const std::string filename =
- std::string("src/decoder/testdata/") + basename + ".astc";
-
- std::string result = LoadFile(filename);
- // Don't parse the header here, we already know what kind of astc encoding it
- // is.
- if (result.size() < 16) {
- return "";
- } else {
- return result.substr(16);
- }
-}
-
-static inline void LoadGoldenBmp(const std::string& path, ImageBuffer* result) {
- constexpr size_t kBmpHeaderSize = 54;
-
- SCOPED_TRACE(testing::Message() << "LoadGoldenBmp " << path);
-
- const std::string data = LoadFile(path);
- ASSERT_FALSE(data.empty()) << "Failed to open golden image: " << path;
-
- ASSERT_GE(data.size(), kBmpHeaderSize);
- ASSERT_EQ('B', data[0]);
- ASSERT_EQ('M', data[1]);
-
- uint32_t dataPos = *reinterpret_cast<const uint32_t*>(&data[0x0A]);
- uint32_t imageSize = *reinterpret_cast<const uint32_t*>(&data[0x22]);
- const uint16_t bitsPerPixel = *reinterpret_cast<const uint16_t*>(&data[0x1C]);
- int width = *reinterpret_cast<const int*>(&data[0x12]);
- int height = *reinterpret_cast<const int*>(&data[0x16]);
-
- SCOPED_TRACE(testing::Message()
- << "dataPos=" << dataPos << ", imageSize=" << imageSize
- << ", bitsPerPixel=" << bitsPerPixel << ", width=" << width
- << ", height=" << height);
-
- if (height < 0) {
- height = -height;
- }
-
- if (imageSize == 0) {
- imageSize = width * height * 3;
- }
-
- if (dataPos < kBmpHeaderSize) {
- dataPos = kBmpHeaderSize;
- }
-
- ASSERT_TRUE(bitsPerPixel == 24 || bitsPerPixel == 32)
- << "BMP bits per pixel mismatch, expected 24 or 32";
-
- result->Allocate(width, height, bitsPerPixel == 24 ? 3 : 4);
- ASSERT_LE(imageSize, result->DataSize());
-
- std::vector<uint8_t>& resultData = result->Data();
- const size_t stride = result->Stride();
-
- // Copy the data row-by-row to make sure that stride is right.
- for (size_t row = 0; row < static_cast<size_t>(height); ++row) {
- memcpy(&resultData[row * stride], &data[dataPos + row * stride],
- width * bitsPerPixel / 8);
- }
-
- if (bitsPerPixel == 32) {
- // Swizzle the data from ABGR to ARGB.
- for (size_t row = 0; row < static_cast<size_t>(height); ++row) {
- uint8_t* rowData = resultData.data() + row * stride;
-
- for (size_t i = 3; i < stride; i += 4) {
- const uint8_t b = rowData[i - 3];
- rowData[i - 3] = rowData[i - 1];
- rowData[i - 1] = b;
- }
- }
- } else {
- // Swizzle the data from BGR to RGB.
- for (size_t row = 0; row < static_cast<size_t>(height); ++row) {
- uint8_t* rowData = resultData.data() + row * stride;
-
- for (size_t i = 2; i < stride; i += 3) {
- const uint8_t tmp = rowData[i - 2];
- rowData[i - 2] = rowData[i];
- rowData[i] = tmp;
- }
- }
- }
-}
-
-static inline void CompareSumOfSquaredDifferences(const ImageBuffer& golden,
- const ImageBuffer& image,
- double threshold) {
- ASSERT_EQ(golden.DataSize(), image.DataSize());
- ASSERT_EQ(golden.Stride(), image.Stride());
- ASSERT_EQ(golden.BytesPerPixel(), image.BytesPerPixel());
-
- const std::vector<uint8_t>& image_data = image.Data();
- const std::vector<uint8_t>& golden_data = golden.Data();
-
- double sum = 0.0;
- for (size_t i = 0; i < image_data.size(); ++i) {
- const double diff = static_cast<double>(image_data[i]) - golden_data[i];
- sum += diff * diff;
- }
-
- EXPECT_LE(sum, threshold * image_data.size())
- << "Per pixel " << (sum / image_data.size())
- << ", expected <= " << threshold;
- if (sum > threshold * image_data.size()) {
- // Fall back to comparison which will dump first chunk of vector.
- EXPECT_EQ(golden_data, image_data);
- }
-}
diff --git a/third-party/astc-codec/src/decoder/test/integer_sequence_codec_test.cc b/third-party/astc-codec/src/decoder/test/integer_sequence_codec_test.cc
deleted file mode 100644
index 120e8b07..00000000
--- a/third-party/astc-codec/src/decoder/test/integer_sequence_codec_test.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/integer_sequence_codec.h"
-#include "src/base/uint128.h"
-
-#include <random>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-using astc_codec::base::UInt128;
-using astc_codec::base::BitStream;
-using astc_codec::IntegerSequenceCodec;
-using astc_codec::IntegerSequenceEncoder;
-using astc_codec::IntegerSequenceDecoder;
-
-namespace {
-
-// Make sure that the counts returned for a specific range match what's
-// expected. In particular, make sure that it fits with Table C.2.7
-TEST(ASTCIntegerSequenceCodecTest, TestGetCountsForRange) {
- std::array<int, 3> kExpectedCounts[31] = {
- {{ 0, 0, 1 }}, // 1
- {{ 1, 0, 0 }}, // 2
- {{ 0, 0, 2 }}, // 3
- {{ 0, 1, 0 }}, // 4
- {{ 1, 0, 1 }}, // 5
- {{ 0, 0, 3 }}, // 6
- {{ 0, 0, 3 }}, // 7
- {{ 0, 1, 1 }}, // 8
- {{ 0, 1, 1 }}, // 9
- {{ 1, 0, 2 }}, // 10
- {{ 1, 0, 2 }}, // 11
- {{ 0, 0, 4 }}, // 12
- {{ 0, 0, 4 }}, // 13
- {{ 0, 0, 4 }}, // 14
- {{ 0, 0, 4 }}, // 15
- {{ 0, 1, 2 }}, // 16
- {{ 0, 1, 2 }}, // 17
- {{ 0, 1, 2 }}, // 18
- {{ 0, 1, 2 }}, // 19
- {{ 1, 0, 3 }}, // 20
- {{ 1, 0, 3 }}, // 21
- {{ 1, 0, 3 }}, // 22
- {{ 1, 0, 3 }}, // 23
- {{ 0, 0, 5 }}, // 24
- {{ 0, 0, 5 }}, // 25
- {{ 0, 0, 5 }}, // 26
- {{ 0, 0, 5 }}, // 27
- {{ 0, 0, 5 }}, // 28
- {{ 0, 0, 5 }}, // 29
- {{ 0, 0, 5 }}, // 30
- {{ 0, 0, 5 }}, // 31
- };
-
- int t, q, b;
- for (int i = 1; i < 32; ++i) {
- IntegerSequenceCodec::GetCountsForRange(i, &t, &q, &b);
- EXPECT_EQ(t, kExpectedCounts[i - 1][0]);
- EXPECT_EQ(q, kExpectedCounts[i - 1][1]);
- EXPECT_EQ(b, kExpectedCounts[i - 1][2]);
- }
-
- ASSERT_DEATH(IntegerSequenceCodec::GetCountsForRange(0, &t, &q, &b), "");
- ASSERT_DEATH(IntegerSequenceCodec::GetCountsForRange(256, &t, &q, &b), "");
-
- IntegerSequenceCodec::GetCountsForRange(1, &t, &q, &b);
- EXPECT_EQ(t, 0);
- EXPECT_EQ(q, 0);
- EXPECT_EQ(b, 1);
-}
-
-// Test to make sure that we're calculating the number of bits needed to
-// encode a given number of values based on the range of the values.
-TEST(ASTCIntegerSequenceCodecTest, TestNumBitsForCounts) {
- int trits = 0;
- int quints = 0;
- int bits = 0;
-
- // A range of one should have single bits, so n 1-bit values should be n bits.
- trits = 0;
- quints = 0;
- bits = 1;
- for (int i = 0; i < 64; ++i) {
- EXPECT_EQ(IntegerSequenceCodec::GetBitCount(i, trits, quints, bits), i);
- EXPECT_EQ(IntegerSequenceCodec::GetBitCountForRange(i, 1), i);
- }
-
- // Similarly, N two-bit values should be 2n bits...
- trits = 0;
- quints = 0;
- bits = 2;
- for (int i = 0; i < 64; ++i) {
- int bit_counts = IntegerSequenceCodec::GetBitCount(i, trits, quints, bits);
- EXPECT_EQ(bit_counts, 2 * i);
- EXPECT_EQ(IntegerSequenceCodec::GetBitCountForRange(i, 3), 2 * i);
- }
-
- // Trits are a bit more complicated -- there are five trits in a block, so
- // if we encode 15 values with 3 bits each in trits, we'd get three blocks,
- // each with eight bits of trits.
- trits = 1;
- quints = 0;
- bits = 3;
- EXPECT_EQ(IntegerSequenceCodec::GetBitCount(15, trits, quints, bits),
- 8 * 3 + 15 * 3);
- EXPECT_EQ(IntegerSequenceCodec::GetBitCountForRange(15, 23),
- IntegerSequenceCodec::GetBitCount(15, trits, quints, bits));
-
- // However, if instead we encode 13 values, we don't need to use the remaining
- // two values, so we only need bits as they will be encoded. As it turns out,
- // this means we can avoid three bits in the final block (one for the high
- // order trit encoding and two for one of the values), resulting in 47 bits.
- trits = 1;
- quints = 0;
- bits = 2;
- EXPECT_EQ(IntegerSequenceCodec::GetBitCount(13, trits, quints, bits), 47);
- EXPECT_EQ(IntegerSequenceCodec::GetBitCountForRange(13, 11),
- IntegerSequenceCodec::GetBitCount(13, trits, quints, bits));
-
- // Quints have a similar property -- if we encode six values using a quint and
- // four bits, then we have two quint blocks each with three values and a seven
- // bit encoded quint triplet...
- trits = 0;
- quints = 1;
- bits = 4;
- EXPECT_EQ(IntegerSequenceCodec::GetBitCount(6, trits, quints, bits),
- 7 * 2 + 6 * 4);
- EXPECT_EQ(IntegerSequenceCodec::GetBitCountForRange(6, 79),
- IntegerSequenceCodec::GetBitCount(6, trits, quints, bits));
-
- // If we have fewer values than blocks we can again avoid about 2 + nbits
- // bits...
- trits = 0;
- quints = 1;
- bits = 3;
- EXPECT_EQ(IntegerSequenceCodec::GetBitCount(7, trits, quints, bits),
- /* first two quint blocks */ 7 * 2 +
- /* first two blocks of bits */ 6 * 3 +
- /* last quint block without the high order four bits */ 3 +
- /* last block with one set of three bits */ 3);
-}
-
-// Tests that the encoder knows how to encode values of the form 5*2^k.
-TEST(ASTCIntegerSequenceCodecTest, TestQuintCodec) {
- // In this case, k = 4
-
- // Setup bit src/sink
- BitStream<UInt128> bit_sink;
-
- const int kValueRange = 79;
- IntegerSequenceEncoder enc(kValueRange);
- enc.AddValue(3);
- enc.AddValue(79);
- enc.AddValue(37);
- enc.Encode(&bit_sink);
-
- // quint: 1000101 m0: 0011 m1: 1111 m2: 0101
- // 100 0100 0111 1101 0010
- // interleaved 10m200m1101m0
- // should be 100 1010 0111 1101 0011 = 0x4A7D3
- EXPECT_EQ(bit_sink.Bits(), 19);
-
- uint64_t encoded = 0;
- bit_sink.GetBits(19, &encoded);
- EXPECT_EQ(encoded, 0x4A7D3);
-
- // Now check that decoding it works as well
- BitStream<UInt128> bit_src(encoded, 19);
-
- IntegerSequenceDecoder dec(kValueRange);
- auto decoded_vals = dec.Decode(3, &bit_src);
- ASSERT_EQ(decoded_vals.size(), 3);
- EXPECT_EQ(decoded_vals[0], 3);
- EXPECT_EQ(decoded_vals[1], 79);
- EXPECT_EQ(decoded_vals[2], 37);
-}
-
-// Tests that the encoder knows how to encode values of the form 3*2^k.
-TEST(ASTCIntegerSequenceCodecTest, TestTritCodec) {
- uint64_t encoded = 0;
-
- // Setup bit src/sink
- BitStream<UInt128> bit_sink(encoded, 0);
-
- const int kValueRange = 11;
- IntegerSequenceEncoder enc(kValueRange);
- enc.AddValue(7);
- enc.AddValue(5);
- enc.AddValue(3);
- enc.AddValue(6);
- enc.AddValue(10);
- enc.Encode(&bit_sink);
-
- EXPECT_EQ(bit_sink.Bits(), 18);
-
- bit_sink.GetBits(18, &encoded);
- EXPECT_EQ(encoded, 0x37357);
-
- // Now check that decoding it works as well
- BitStream<UInt128> bit_src(encoded, 19);
-
- IntegerSequenceDecoder dec(kValueRange);
- auto decoded_vals = dec.Decode(5, &bit_src);
- ASSERT_EQ(decoded_vals.size(), 5);
- EXPECT_EQ(decoded_vals[0], 7);
- EXPECT_EQ(decoded_vals[1], 5);
- EXPECT_EQ(decoded_vals[2], 3);
- EXPECT_EQ(decoded_vals[3], 6);
- EXPECT_EQ(decoded_vals[4], 10);
-}
-
-// Test a specific quint encoding/decoding. This test makes sure that the way we
-// encode and decode integer sequences matches what we should expect out of the
-// reference ASTC encoder.
-TEST(ASTCIntegerSequenceCodecTest, TestDecodeThenEncode) {
- std::vector<int> vals = {{ 16, 18, 17, 4, 7, 14, 10, 0 }};
- const uint64_t kValEncoding = 0x2b9c83dc;
-
- BitStream<UInt128> bit_src(kValEncoding, 64);
- IntegerSequenceDecoder dec(19);
- auto decoded_vals = dec.Decode(8, &bit_src);
- ASSERT_EQ(decoded_vals.size(), vals.size());
- for (size_t i = 0; i < decoded_vals.size(); ++i) {
- EXPECT_EQ(decoded_vals[i], vals[i]);
- }
-
- // Setup bit src/sink
- BitStream<UInt128> bit_sink;
- IntegerSequenceEncoder enc(19);
- for (const auto& v : vals) {
- enc.AddValue(v);
- }
- enc.Encode(&bit_sink);
- EXPECT_EQ(bit_sink.Bits(), 35);
-
- uint64_t encoded = 0;
- EXPECT_TRUE(bit_sink.GetBits(35, &encoded));
- EXPECT_EQ(encoded, kValEncoding)
- << std::hex << encoded << " -- " << kValEncoding;
-}
-
-// Same as the previous test, except it uses a trit encoding rather than a
-// quint encoding.
-TEST(ASTCIntegerSequenceCodecTest, TestDecodeThenEncodeTrits) {
- std::vector<int> vals = {{ 6, 0, 0, 2, 0, 0, 0, 0, 8, 0, 0, 0, 0, 8, 8, 0 }};
- const uint64_t kValEncoding = 0x0004c0100001006ULL;
-
- BitStream<UInt128> bit_src(kValEncoding, 64);
- IntegerSequenceDecoder dec(11);
- auto decoded_vals = dec.Decode(vals.size(), &bit_src);
- ASSERT_EQ(decoded_vals.size(), vals.size());
- for (size_t i = 0; i < decoded_vals.size(); ++i) {
- EXPECT_EQ(decoded_vals[i], vals[i]);
- }
-
- // Setup bit src/sink
- BitStream<UInt128> bit_sink;
- IntegerSequenceEncoder enc(11);
- for (const auto& v : vals) {
- enc.AddValue(v);
- }
- enc.Encode(&bit_sink);
- EXPECT_EQ(bit_sink.Bits(), 58);
-
- uint64_t encoded = 0;
- EXPECT_TRUE(bit_sink.GetBits(58, &encoded));
- EXPECT_EQ(encoded, kValEncoding)
- << std::hex << encoded << " -- " << kValEncoding;
-}
-
-// Generate a random sequence of integer codings with different ranges to test
-// the reciprocability of our codec (encoded sequences should be able to
-// decoded)
-TEST(ASTCIntegerSequenceCodecTest, TestRandomReciprocation) {
- std::mt19937 mt(0xbad7357);
- std::uniform_int_distribution<int> rand(0, 255);
-
- for (int test = 0; test < 1600; ++test) {
- // Generate a random number of values and a random range
- int num_vals = 4 + rand(mt) % 44; // Up to 48 weights in a grid
- int range = 1 + rand(mt) % 63;
-
- // If this produces a bit pattern larger than our buffer, then ignore
- // it... we already know what our bounds are for the integer sequences
- int num_bits = IntegerSequenceCodec::GetBitCountForRange(num_vals, range);
- if (num_bits >= 64) {
- continue;
- }
-
- std::vector<int> generated_vals(num_vals);
- for (auto& val : generated_vals) {
- val = rand(mt) % (range + 1);
- }
-
- // Encode the values using the
- BitStream<UInt128> bit_sink;
-
- // Add them to the encoder
- IntegerSequenceEncoder enc(range);
- for (int v : generated_vals) {
- enc.AddValue(v);
- }
- enc.Encode(&bit_sink);
-
- uint64_t encoded = 0;
- bit_sink.GetBits(bit_sink.Bits(), &encoded);
- ASSERT_GE(encoded, 0);
- EXPECT_LT(encoded, 1ULL << num_bits);
-
- BitStream<UInt128> bit_src(encoded, 64);
-
- IntegerSequenceDecoder dec(range);
- auto decoded_vals = dec.Decode(num_vals, &bit_src);
-
- ASSERT_EQ(decoded_vals.size(), generated_vals.size());
- for (size_t i = 0; i < decoded_vals.size(); ++i) {
- EXPECT_EQ(decoded_vals[i], generated_vals[i]);
- }
- }
-}
-
-} // namespace
diff --git a/third-party/astc-codec/src/decoder/test/intermediate_astc_block_test.cc b/third-party/astc-codec/src/decoder/test/intermediate_astc_block_test.cc
deleted file mode 100644
index 41861cb9..00000000
--- a/third-party/astc-codec/src/decoder/test/intermediate_astc_block_test.cc
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/intermediate_astc_block.h"
-#include "src/decoder/test/image_utils.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <string>
-
-namespace astc_codec {
-
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::HasSubstr;
-using ::testing::SizeIs;
-using ::testing::TestWithParam;
-using ::testing::ValuesIn;
-
-// Test to make sure that unpacking an error block returns false.
-TEST(IntermediateASTCBlockTest, TestUnpackError) {
- const PhysicalASTCBlock kErrorBlock(base::UInt128(0));
- EXPECT_FALSE(UnpackVoidExtent(kErrorBlock));
- EXPECT_FALSE(UnpackIntermediateBlock(kErrorBlock));
-}
-
-// Test to make sure that if we don't populate our weight data in the
-// intermediate block than the resulting color range should error due to the
-// mismatch.
-TEST(IntermediateASTCBlockTest, TestEndpointRangeErrorOnNotSettingWeights) {
- IntermediateBlockData data;
- data.weight_range = 15;
- for (auto& ep : data.endpoints) {
- ep.mode = ColorEndpointMode::kLDRRGBDirect;
- }
- data.weight_grid_dim_x = 6;
- data.weight_grid_dim_y = 6;
- EXPECT_EQ(-1, EndpointRangeForBlock(data));
-
- base::UInt128 dummy;
- auto err_str = Pack(data, &dummy);
- EXPECT_TRUE(err_str.hasValue());
- EXPECT_THAT(err_str.value(), HasSubstr("Incorrect number of weights"));
-}
-
-// Test to make sure that if we run out of bits, then we should say so.
-TEST(IntermediateASTCBlockTest, TestEndpointRangeErrorOnNotEnoughBits) {
- IntermediateBlockData data;
- data.weight_range = 1;
- data.partition_id = 0;
- data.endpoints.resize(3);
- for (auto& ep : data.endpoints) {
- ep.mode = ColorEndpointMode::kLDRRGBDirect;
- }
- data.weight_grid_dim_x = 8;
- data.weight_grid_dim_y = 8;
- EXPECT_EQ(-2, EndpointRangeForBlock(data));
-
- // Resize the weights to get past the error that they do not match the grid
- // dimensions.
- data.weights.resize(64);
-
- base::UInt128 dummy;
- auto err_str = Pack(data, &dummy);
- EXPECT_TRUE(err_str.hasValue());
- EXPECT_THAT(err_str.value(), HasSubstr("illegal color range"));
-}
-
-// Test to make sure that as we increase the number of weights, we decrease the
-// allowable range of colors
-TEST(IntermediateASTCBlockTest, TestEndpointRangeForBlock) {
- IntermediateBlockData data;
- data.weight_range = 2;
- data.endpoints.resize(2);
- data.dual_plane_channel.clear();
- for (auto& ep : data.endpoints) {
- ep.mode = ColorEndpointMode::kLDRRGBDirect;
- }
-
- // Weight params control how many weights are present in a block
- struct WeightParams {
- int width;
- int height;
-
- // We should sort based on number of weights for these params
- int NumWeights() const { return width * height; }
- bool operator<(const WeightParams& other) const {
- return NumWeights() < other.NumWeights();
- }
- };
-
- std::vector<WeightParams> weight_params;
- for (int y = 2; y < 8; ++y) {
- for (int x = 2; x < 8; ++x) {
- weight_params.emplace_back(WeightParams{x, y});
- }
- }
-
- // Sort weights from fewest to largest such that the allowable color range
- // should be monotonically decreasing
- std::sort(weight_params.begin(), weight_params.end());
-
- // Keep track of the largest available color range and measure that it
- // decreases as we add more weights to our block
- int last_color_range = 255;
- for (const auto& params : weight_params) {
- data.weight_grid_dim_x = params.width;
- data.weight_grid_dim_y = params.height;
-
- const int color_range = EndpointRangeForBlock(data);
- EXPECT_LE(color_range, last_color_range);
- last_color_range = std::min(color_range, last_color_range);
- }
-
- // Make sure that we actually changed it at some point.
- EXPECT_LT(last_color_range, 255);
-}
-
-// Test to make sure that unpacking an legitimate ASTC block returns the encoded
-// values that we expect.
-TEST(IntermediateASTCBlockTest, TestUnpackNonVoidExtentBlock) {
- PhysicalASTCBlock blk(0x0000000001FE000173ULL);
- auto b = UnpackIntermediateBlock(blk);
- ASSERT_TRUE(b);
-
- const auto& data = b.value();
- EXPECT_EQ(data.weight_grid_dim_x, 6);
- EXPECT_EQ(data.weight_grid_dim_y, 5);
- EXPECT_EQ(data.weight_range, 7);
-
- EXPECT_FALSE(data.partition_id);
- EXPECT_FALSE(data.dual_plane_channel);
-
- ASSERT_EQ(data.weights.size(), 30);
- for (auto weight : data.weights) {
- EXPECT_EQ(weight, 0);
- }
-
- ASSERT_EQ(data.endpoints.size(), 1);
- for (const auto& ep_data : data.endpoints) {
- EXPECT_EQ(ep_data.mode, ColorEndpointMode::kLDRLumaDirect);
- ASSERT_EQ(ep_data.colors.size(), 2);
- EXPECT_EQ(ep_data.colors[0], 0);
- EXPECT_EQ(ep_data.colors[1], 255);
- }
-}
-
-// Make sure that we can pack blocks that aren't void extent blocks. (In other
-// words, can we actually deal with intermediate ASTC data).
-TEST(IntermediateASTCBlockTest, TestPackNonVoidExtentBlock) {
- IntermediateBlockData data;
-
- data.weight_grid_dim_x = 6;
- data.weight_grid_dim_y = 5;
- data.weight_range = 7;
-
- data.partition_id = {};
- data.dual_plane_channel = {};
-
- data.weights.resize(30);
- for (auto& weight : data.weights) {
- weight = 0;
- }
-
- data.endpoints.resize(1);
- for (auto& ep_data : data.endpoints) {
- ep_data.mode = ColorEndpointMode::kLDRLumaDirect;
- ep_data.colors.resize(2);
- ep_data.colors[0] = 0;
- ep_data.colors[1] = 255;
- }
-
- base::UInt128 packed;
- auto error_str = Pack(data, &packed);
- ASSERT_FALSE(error_str) << (error_str ? error_str.value() : std::string(""));
- EXPECT_EQ(packed, 0x0000000001FE000173ULL);
-}
-
-// Make sure that we can unpack void extent blocks
-TEST(IntermediateASTCBlockTest, TestUnpackVoidExtentBlock) {
- PhysicalASTCBlock void_extent_block(0xFFFFFFFFFFFFFDFCULL);
-
- auto b = UnpackVoidExtent(void_extent_block);
- ASSERT_TRUE(b);
-
- const auto& data = b.value();
- EXPECT_EQ(data.r, 0);
- EXPECT_EQ(data.g, 0);
- EXPECT_EQ(data.b, 0);
- EXPECT_EQ(data.a, 0);
- for (const auto& coord : data.coords) {
- EXPECT_EQ(coord, (1 << 13) - 1);
- }
-
- base::UInt128 more_interesting(0xdeadbeefdeadbeefULL, 0xFFF8003FFE000DFCULL);
- b = UnpackVoidExtent(PhysicalASTCBlock(more_interesting));
- ASSERT_TRUE(b);
-
- const auto& other_data = b.value();
- EXPECT_EQ(other_data.r, 0xbeef);
- EXPECT_EQ(other_data.g, 0xdead);
- EXPECT_EQ(other_data.b, 0xbeef);
- EXPECT_EQ(other_data.a, 0xdead);
- EXPECT_EQ(other_data.coords[0], 0);
- EXPECT_EQ(other_data.coords[1], 8191);
- EXPECT_EQ(other_data.coords[2], 0);
- EXPECT_EQ(other_data.coords[3], 8191);
-}
-
-// Make sure that we can pack void extent blocks and void extent data.
-TEST(IntermediateASTCBlockTest, TestPackVoidExtentBlock) {
- VoidExtentData data;
- data.r = 0;
- data.g = 0;
- data.b = 0;
- data.a = 0;
- for (auto& coord : data.coords) {
- coord = (1 << 13) - 1;
- }
-
- base::UInt128 packed;
- auto error_str = Pack(data, &packed);
- ASSERT_FALSE(error_str) << (error_str ? error_str.value() : std::string(""));
- EXPECT_EQ(packed, 0xFFFFFFFFFFFFFDFCULL);
-
- data.r = 0xbeef;
- data.g = 0xdead;
- data.b = 0xbeef;
- data.a = 0xdead;
- data.coords[0] = 0;
- data.coords[1] = 8191;
- data.coords[2] = 0;
- data.coords[3] = 8191;
-
- error_str = Pack(data, &packed);
- ASSERT_FALSE(error_str) << (error_str ? error_str.value() : std::string(""));
- EXPECT_EQ(packed,
- base::UInt128(0xdeadbeefdeadbeefULL, 0xFFF8003FFE000DFCULL));
-}
-
-// Make sure that the color endpoint mode is properly repacked. This test case
-// was created as a bug during testing.
-TEST(IntermediateASTCBlockTest, TestPackUnpackWithSameCEM) {
- base::UInt128 orig(0xe8e8eaea20000980ULL, 0x20000200cb73f045ULL);
-
- auto b = UnpackIntermediateBlock(PhysicalASTCBlock(orig));
- ASSERT_TRUE(b);
-
- base::UInt128 repacked;
- auto err_str = Pack(b.value(), &repacked);
- ASSERT_FALSE(err_str) << (err_str ? err_str.value() : std::string(""));
-
- EXPECT_EQ(repacked, orig);
-
- // Test case #2
- orig = base::UInt128(0x3300c30700cb01c5ULL, 0x0573907b8c0f6879ULL);
- b = UnpackIntermediateBlock(PhysicalASTCBlock(orig));
- ASSERT_TRUE(b);
-
- err_str = Pack(b.value(), &repacked);
- ASSERT_FALSE(err_str) << (err_str ? err_str.value() : std::string(""));
- EXPECT_EQ(repacked, orig);
-}
-
-// Test that we can encode/decode a block that uses a very large gap
-// between weight and endpoint data.
-TEST(IntermediateASTCBlockTest, TestPackingWithLargeGap) {
- // We can construct this block by doing the following:
- // -- choose a block mode that only gives 24 weight bits
- // -- choose the smallest endpoint mode: grayscale direct
- // -- make sure there are no partitions
- const base::UInt128 orig(0xBEDEAD0000000000ULL, 0x0000000001FE032EULL);
- const auto b = UnpackIntermediateBlock(PhysicalASTCBlock(orig));
- ASSERT_TRUE(b);
-
- const auto& data = b.value();
- EXPECT_EQ(data.weight_grid_dim_x, 2);
- EXPECT_EQ(data.weight_grid_dim_y, 3);
- EXPECT_EQ(data.weight_range, 15);
-
- EXPECT_FALSE(data.partition_id);
- EXPECT_FALSE(data.dual_plane_channel);
-
- ASSERT_EQ(data.endpoints.size(), 1);
- EXPECT_EQ(data.endpoints.at(0).mode, ColorEndpointMode::kLDRLumaDirect);
-
- ASSERT_EQ(data.endpoints.at(0).colors.size(), 2);
- EXPECT_EQ(data.endpoints.at(0).colors.at(0), 255);
- EXPECT_EQ(data.endpoints.at(0).colors.at(1), 0);
-
- // Now encode it again
- base::UInt128 repacked;
- const auto err_str = Pack(b.value(), &repacked);
- EXPECT_EQ(orig, repacked) << (err_str ? err_str.value() : std::string(""));
-}
-
-// Take a block that is encoded using direct luma with full byte values and see
-// if we properly set the endpoint range.
-TEST(IntermediateASTCBlockTest, TestEndpointRange) {
- PhysicalASTCBlock blk(0x0000000001FE000173ULL);
- EXPECT_TRUE(blk.ColorValuesRange().hasValue());
- EXPECT_EQ(blk.ColorValuesRange().valueOr(0), 255);
-
- auto b = UnpackIntermediateBlock(blk);
- ASSERT_TRUE(b);
-
- const auto& data = b.value();
- ASSERT_THAT(data.endpoints, SizeIs(1));
- EXPECT_THAT(data.endpoints[0].mode, Eq(ColorEndpointMode::kLDRLumaDirect));
- EXPECT_THAT(data.endpoints[0].colors, ElementsAre(0, 255));
- EXPECT_TRUE(data.endpoint_range.hasValue());
- EXPECT_EQ(data.endpoint_range.valueOr(0), 255);
-}
-
-struct ImageTestParams {
- std::string image_name;
- int checkered_dim;
-};
-
-static void PrintTo(const ImageTestParams& params, std::ostream* os) {
- *os << "ImageTestParams(" << params.image_name << ")";
-}
-
-class IntermediateASTCBlockTest : public TestWithParam<ImageTestParams> { };
-
-// Test whether or not a real-world ASTC implementation can be unpacked and
-// then repacked into the same implementation. In conjunction with the other
-// tests, we make sure that we can recreate ASTC blocks that we have previously
-// unpacked.
-TEST_P(IntermediateASTCBlockTest, TestPackUnpack) {
- const auto& params = GetParam();
- const int astc_dim = 8;
- const int img_dim = params.checkered_dim * astc_dim;
- const std::string astc = LoadASTCFile(params.image_name);
-
- // Make sure that unpacking and repacking all of the blocks works...
- const int kNumASTCBlocks = (img_dim / astc_dim) * (img_dim / astc_dim);
- for (int i = 0; i < kNumASTCBlocks; ++i) {
- base::UInt128 block_bits;
- memcpy(&block_bits, astc.data() + PhysicalASTCBlock::kSizeInBytes * i,
- PhysicalASTCBlock::kSizeInBytes);
-
- const PhysicalASTCBlock block(block_bits);
-
- base::UInt128 repacked;
- if (block.IsVoidExtent()) {
- auto b = UnpackVoidExtent(block);
- ASSERT_TRUE(b);
-
- auto err_str = Pack(b.value(), &repacked);
- ASSERT_FALSE(err_str) << (err_str ? err_str.value() : std::string(""));
- } else {
- auto b = UnpackIntermediateBlock(block);
- ASSERT_TRUE(b);
-
- // Check to see that we properly set the endpoint range when we decoded
- // the block.
- auto& block_data = b.value();
- EXPECT_EQ(block_data.endpoint_range, block.ColorValuesRange());
-
- // Reset the endpoint range here to see if we correctly reconstruct it
- // below
- block_data.endpoint_range = {};
-
- auto err_str = Pack(b.value(), &repacked);
- ASSERT_FALSE(err_str) << (err_str ? err_str.value() : std::string(""));
- }
-
- // You would expect the following line to be enough:
- // EXPECT_EQ(repacked, block.GetBlockBits())
- // ... except that the ASTC encoder makes some interesting decisions
- // about how to encode the same logical bits. One example is that
- // sometimes if all partitions share an endpoint mode, the encoded
- // block will not use the shared CEM mode, and rather list each
- // partition's mode explicitly. For that reason, we just need to make as
- // close of an approximation as possible that we decode to the same
- // physical values.
-
- PhysicalASTCBlock pb(repacked);
- ASSERT_FALSE(pb.IsIllegalEncoding());
-
- base::UInt128 pb_color_mask =
- (base::UInt128(1) << pb.NumColorBits().value()) - 1;
- base::UInt128 pb_color_bits =
- pb.GetBlockBits() >> pb.ColorStartBit().value();
- pb_color_bits &= pb_color_mask;
-
- base::UInt128 b_color_mask =
- (base::UInt128(1) << pb.NumColorBits().value()) - 1;
- base::UInt128 b_color_bits =
- block.GetBlockBits() >> block.ColorStartBit().value();
- b_color_bits &= b_color_mask;
-
- EXPECT_EQ(pb_color_mask, b_color_mask);
- EXPECT_EQ(pb_color_bits, b_color_bits);
-
- EXPECT_EQ(pb.IsVoidExtent(), block.IsVoidExtent());
- EXPECT_EQ(pb.VoidExtentCoords(), block.VoidExtentCoords());
-
- EXPECT_EQ(pb.WeightGridDims(), block.WeightGridDims());
- EXPECT_EQ(pb.WeightRange(), block.WeightRange());
- EXPECT_EQ(pb.NumWeightBits(), block.NumWeightBits());
- EXPECT_EQ(pb.WeightStartBit(), block.WeightStartBit());
-
- EXPECT_EQ(pb.IsDualPlane(), block.IsDualPlane());
- EXPECT_EQ(pb.DualPlaneChannel(), block.DualPlaneChannel());
-
- EXPECT_EQ(pb.NumPartitions(), block.NumPartitions());
- EXPECT_EQ(pb.PartitionID(), block.PartitionID());
-
- EXPECT_EQ(pb.NumColorValues(), block.NumColorValues());
- EXPECT_EQ(pb.ColorValuesRange(), block.ColorValuesRange());
-
- for (int j = 0; j < pb.NumPartitions().valueOr(0); ++j) {
- EXPECT_EQ(pb.GetEndpointMode(j), block.GetEndpointMode(j));
- }
- }
-}
-
-std::vector<ImageTestParams> GetImageTestParams() {
- return {
- // image_name checkered_dim
- { "checkered_4", 4 },
- { "checkered_5", 5 },
- { "checkered_6", 6 },
- { "checkered_7", 7 },
- { "checkered_8", 8 },
- { "checkered_9", 9 },
- { "checkered_10", 10 },
- { "checkered_11", 11 },
- { "checkered_12", 12 },
- };
-}
-
-INSTANTIATE_TEST_CASE_P(Checkered, IntermediateASTCBlockTest,
- ValuesIn(GetImageTestParams()));
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/test/logical_astc_block_test.cc b/third-party/astc-codec/src/decoder/test/logical_astc_block_test.cc
deleted file mode 100644
index ed85f3fd..00000000
--- a/third-party/astc-codec/src/decoder/test/logical_astc_block_test.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/logical_astc_block.h"
-#include "src/decoder/test/image_utils.h"
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include <fstream>
-#include <string>
-
-namespace astc_codec {
-
-namespace {
-
-using ::testing::Eq;
-using ::testing::ElementsAre;
-using ::testing::TestWithParam;
-using ::testing::ValuesIn;
-
-ImageBuffer LoadGoldenImageWithAlpha(std::string basename) {
- const std::string filename = std::string("src/decoder/testdata/") + basename + ".bmp";
- ImageBuffer result;
- LoadGoldenBmp(filename, &result);
- EXPECT_EQ(result.BytesPerPixel(), 4);
- return result;
-}
-
-ImageBuffer LoadGoldenImage(std::string basename) {
- const std::string filename = std::string("src/decoder/testdata/") + basename + ".bmp";
- ImageBuffer result;
- LoadGoldenBmp(filename, &result);
- EXPECT_EQ(result.BytesPerPixel(), 3);
- return result;
-}
-
-struct ImageTestParams {
- std::string image_name;
- bool has_alpha;
- Footprint footprint;
- int width;
- int height;
-};
-
-static void PrintTo(const ImageTestParams& params, std::ostream* os) {
- *os << "ImageTestParams(" << params.image_name << ", "
- << params.width << "x" << params.height << ", "
- << (params.has_alpha ? "RGBA" : "RGB") << ", "
- << "footprint " << params.footprint.Width() << "x"
- << params.footprint.Height() << ")";
-}
-
-class LogicalASTCBlockTest : public TestWithParam<ImageTestParams> { };
-
-// Test to make sure that reading out color values from blocks is not
-// terribly wrong. To do so, we compress an image and then decompress it
-// using our logical blocks and the library. The difference between the
-// decoded images should be minimal.
-TEST_P(LogicalASTCBlockTest, ImageWithFootprint) {
- const auto& params = GetParam();
- const std::string astc = LoadASTCFile(params.image_name);
-
- ImageBuffer our_decoded_image;
- our_decoded_image.Allocate(params.width, params.height, params.has_alpha ? 4 : 3);
-
- const int block_width = params.footprint.Width();
- const int block_height = params.footprint.Height();
-
- base::UInt128 block;
- for (int i = 0; i < astc.size(); i += 16) {
- const int block_index = i / 16;
- const int blocks_wide =
- (params.width + block_width - 1) / block_width;
- const int block_x = block_index % blocks_wide;
- const int block_y = block_index / blocks_wide;
- memcpy(&block, astc.data() + i, sizeof(block));
-
- PhysicalASTCBlock physical_block(block);
- if (physical_block.IsVoidExtent()) {
- auto ve = UnpackVoidExtent(physical_block);
- ASSERT_TRUE(ve) << "ASTC encoder produced invalid block!";
- } else {
- auto ib = UnpackIntermediateBlock(physical_block);
- ASSERT_TRUE(ib) << "ASTC encoder produced invalid block!";
- }
-
- // Make sure that the library doesn't produce incorrect ASTC blocks.
- // This is covered in more depth in other tests in
- // intermediate_astc_block_test and physical_astc_block_test
- auto lb = UnpackLogicalBlock(params.footprint, physical_block);
- ASSERT_TRUE(lb) << "ASTC encoder produced invalid block!";
-
- LogicalASTCBlock logical_block = lb.value();
- const size_t color_size = params.has_alpha ? 4 : 3;
-
- for (int y = 0; y < block_height; ++y) {
- for (int x = 0; x < block_width; ++x) {
- const int px = block_width * block_x + x;
- const int py = block_height * block_y + y;
-
- // Skip out of bounds.
- if (px >= params.width || py >= params.height) {
- continue;
- }
-
- uint8_t* pixel = our_decoded_image(px, py);
- const RgbaColor decoded_color = logical_block.ColorAt(x, y);
- ASSERT_LE(color_size, decoded_color.size());
-
- for (int c = 0; c < color_size; ++c) {
- // All of the pixels should also be 8-bit values.
- ASSERT_GE(decoded_color[c], 0);
- ASSERT_LT(decoded_color[c], 256);
- pixel[c] = decoded_color[c];
- }
- }
- }
- }
-
- // Check that the decoded image is *very* similar to the library decoding
- // of an ASTC texture. They may not be exact due to differences in how we
- // convert a 16-bit float to an 8-bit integer.
- ImageBuffer decoded_image = params.has_alpha ? LoadGoldenImageWithAlpha(params.image_name) : LoadGoldenImage(params.image_name);
- CompareSumOfSquaredDifferences(decoded_image, our_decoded_image, 1.0);
-}
-
-// Test to make sure that a simple gradient image can be compressed and decoded
-// by our logical block representation. This should work with every footprint.
-std::vector<ImageTestParams> GetSyntheticImageTestParams() {
- return {
- // image_name alpha astc footprint width height
- { "footprint_4x4", false, Footprint::Get4x4(), 32, 32 },
- { "footprint_5x4", false, Footprint::Get5x4(), 32, 32 },
- { "footprint_5x5", false, Footprint::Get5x5(), 32, 32 },
- { "footprint_6x5", false, Footprint::Get6x5(), 32, 32 },
- { "footprint_6x6", false, Footprint::Get6x6(), 32, 32 },
- { "footprint_8x5", false, Footprint::Get8x5(), 32, 32 },
- { "footprint_8x6", false, Footprint::Get8x6(), 32, 32 },
- { "footprint_10x5", false, Footprint::Get10x5(), 32, 32 },
- { "footprint_10x6", false, Footprint::Get10x6(), 32, 32 },
- { "footprint_8x8", false, Footprint::Get8x8(), 32, 32 },
- { "footprint_10x8", false, Footprint::Get10x8(), 32, 32 },
- { "footprint_10x10", false, Footprint::Get10x10(), 32, 32 },
- { "footprint_12x10", false, Footprint::Get12x10(), 32, 32 },
- { "footprint_12x12", false, Footprint::Get12x12(), 32, 32 },
- };
-}
-
-INSTANTIATE_TEST_CASE_P(Synthetic, LogicalASTCBlockTest,
- ValuesIn(GetSyntheticImageTestParams()));
-
-// Test to make sure that reading out color values from blocks in a real-world
-// image isn't terribly wrong, either.
-std::vector<ImageTestParams> GetRealWorldImageTestParams() {
- return {
- // image_name alpha astc footprint width height
- { "rgb_4x4", false, Footprint::Get4x4(), 224, 288 },
- { "rgb_6x6", false, Footprint::Get6x6(), 224, 288 },
- { "rgb_8x8", false, Footprint::Get8x8(), 224, 288 },
- { "rgb_12x12", false, Footprint::Get12x12(), 224, 288 },
- { "rgb_5x4", false, Footprint::Get5x4(), 224, 288 }
- };
-}
-
-INSTANTIATE_TEST_CASE_P(RealWorld, LogicalASTCBlockTest,
- ValuesIn(GetRealWorldImageTestParams()));
-
-// Test to make sure that reading out color values from blocks in a real-world
-// image isn't terribly wrong, either.
-std::vector<ImageTestParams> GetTransparentImageTestParams() {
- return {
- // image_name alpha astc footprint width height
- { "atlas_small_4x4", true, Footprint::Get4x4(), 256, 256 },
- { "atlas_small_5x5", true, Footprint::Get5x5(), 256, 256 },
- { "atlas_small_6x6", true, Footprint::Get6x6(), 256, 256 },
- { "atlas_small_8x8", true, Footprint::Get8x8(), 256, 256 },
- };
-}
-
-INSTANTIATE_TEST_CASE_P(Transparent, LogicalASTCBlockTest,
- ValuesIn(GetTransparentImageTestParams()));
-
-// Test to make sure that if we set our endpoints then it's reflected in our
-// color selection
-TEST(LogicalASTCBlockTest, SetEndpoints) {
- LogicalASTCBlock logical_block(Footprint::Get8x8());
-
- // Setup a weight checkerboard
- for (int j = 0; j < 8; ++j) {
- for (int i = 0; i < 8; ++i) {
- if (((i ^ j) & 1) == 1) {
- logical_block.SetWeightAt(i, j, 0);
- } else {
- logical_block.SetWeightAt(i, j, 64);
- }
- }
- }
-
- // Now set the colors to something ridiculous
- logical_block.SetEndpoints({{ 123, 45, 67, 89 }}, {{ 101, 121, 31, 41 }}, 0);
-
- // For each pixel, we expect it to mirror the endpoints in a checkerboard
- // pattern
- for (int j = 0; j < 8; ++j) {
- for (int i = 0; i < 8; ++i) {
- if (((i ^ j) & 1) == 1) {
- EXPECT_THAT(logical_block.ColorAt(i, j), ElementsAre(123, 45, 67, 89));
- } else {
- EXPECT_THAT(logical_block.ColorAt(i, j), ElementsAre(101, 121, 31, 41));
- }
- }
- }
-}
-
-// Test whether or not setting weight values under different circumstances is
-// supported and reflected in the query functions.
-TEST(LogicalASTCBlockTest, SetWeightVals) {
- LogicalASTCBlock logical_block(Footprint::Get4x4());
-
- EXPECT_THAT(logical_block.GetFootprint(), Eq(Footprint::Get4x4()));
-
- // Not a dual plane by default
- EXPECT_FALSE(logical_block.IsDualPlane());
- logical_block.SetWeightAt(2, 3, 2);
-
- // Set the dual plane
- logical_block.SetDualPlaneChannel(0);
- EXPECT_TRUE(logical_block.IsDualPlane());
-
- // This shouldn't have reset our weight
- const LogicalASTCBlock other_block = logical_block;
- EXPECT_THAT(other_block.WeightAt(2, 3), Eq(2));
- EXPECT_THAT(other_block.DualPlaneWeightAt(0, 2, 3), Eq(2));
-
- // If we set the dual plane weight, it shouldn't change the original weight
- // value or the other channels
- logical_block.SetDualPlaneWeightAt(0, 2, 3, 1);
- EXPECT_THAT(logical_block.WeightAt(2, 3), Eq(2));
- EXPECT_THAT(logical_block.DualPlaneWeightAt(0, 2, 3), Eq(1));
- for (int i = 1; i < 4; ++i) {
- EXPECT_THAT(logical_block.DualPlaneWeightAt(i, 2, 3), Eq(2));
- }
-
- // Remove the dual plane
- logical_block.SetDualPlaneChannel(-1);
- EXPECT_FALSE(logical_block.IsDualPlane());
-
- // Now the original dual plane weight should be reset back to the others. Note
- // that we have to call DualPlaneWeightAt from a const logical block since
- // returning a reference to a weight that doesn't exist is illegal.
- const LogicalASTCBlock other_block2 = logical_block;
- EXPECT_THAT(logical_block.WeightAt(2, 3), Eq(2));
- for (int i = 0; i < 4; ++i) {
- EXPECT_EQ(logical_block.WeightAt(2, 3),
- other_block2.DualPlaneWeightAt(i, 2, 3));
- }
-}
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/test/partition_test.cc b/third-party/astc-codec/src/decoder/test/partition_test.cc
deleted file mode 100644
index 63adfb50..00000000
--- a/third-party/astc-codec/src/decoder/test/partition_test.cc
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/partition.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <array>
-#include <random>
-#include <string>
-#include <vector>
-
-namespace {
-
-using ::testing::ElementsAreArray;
-using ::testing::Eq;
-using ::testing::Le;
-using ::testing::Not;
-
-using astc_codec::Footprint;
-using astc_codec::Partition;
-using astc_codec::PartitionMetric;
-using astc_codec::GetASTCPartition;
-using astc_codec::FindClosestASTCPartition;
-
-// Test to make sure that a simple difference between two partitions where
-// most of the values are the same returns what we expect.
-TEST(PartitionTest, TestSimplePartitionMetric) {
- Partition a = {Footprint::Get6x6(), /* num_parts = */ 2,
- /* partition_id = */ {}, /* assignment = */ {}};
- Partition b = a;
-
- a.assignment = {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1,
- };
-
- b.assignment = {
- 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- };
-
- const int dist = PartitionMetric(a, b);
- EXPECT_EQ(dist, 2);
-}
-
-// Test to make sure that if one partition is a subset of another that we still
-// return the proper difference against the subset of the larger one.
-TEST(PartitionDeathTest, TestPartitionMetric) {
- Partition a = {Footprint::Get4x4(), /* num_parts = */ 2,
- /* partition_id = */ {}, /* assignment = */ {}};
- Partition b = {Footprint::Get6x6(), /* num_parts = */ 2,
- /* partition_id = */ {}, /* assignment = */ {}};
-
- a.assignment = {{
- 1, 1, 1, 1,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- }};
-
- b.assignment = {{
- 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 0, 1, 1, 0, 0,
- }};
-
- EXPECT_DEATH(PartitionMetric(a, b), "");
-}
-
-// Test to make sure that even if we have different numbers of subsets for each
-// partition, that the returned value is what we'd expect.
-TEST(PartitionTest, TestDiffPartsPartitionMetric) {
- Partition a = {Footprint::Get4x4(), /* num_parts = */ 2,
- /* partition_id = */ {}, /* assignment = */ {}};
- Partition b = {Footprint::Get4x4(), /* num_parts = */ 3,
- /* partition_id = */ {}, /* assignment = */ {}};
-
- a.assignment = {{
- 2, 2, 2, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- }};
-
- b.assignment = {{
- 1, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- }};
-
- const int dist = PartitionMetric(a, b);
- EXPECT_EQ(dist, 3);
-}
-
-// An additional sanity check test that makes sure that we're not always mapping
-// zero to zero in our tests.
-TEST(PartitionTest, TestDiffMappingPartitionMetric) {
- Partition a = {Footprint::Get4x4(), /* num_parts = */ 2,
- /* partition_id = */ {}, /* assignment = */ {}};
- Partition b = {Footprint::Get4x4(), /* num_parts = */ 3,
- /* partition_id = */ {}, /* assignment = */ {}};
-
- a.assignment = {{
- 0, 1, 2, 2,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- }};
-
- b.assignment = {{
- 1, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- }};
-
- const int dist = PartitionMetric(a, b);
- EXPECT_EQ(dist, 1);
-}
-
-// Finally, if we grab an ASTC partition and modify it a tad, the closest
-// partition should still be the same ASTC partition.
-TEST(PartitionTest, TestFindingASTCPartition) {
- const Partition astc = GetASTCPartition(Footprint::Get12x12(), 3, 0x3CB);
- Partition almost_astc = astc;
- almost_astc.assignment[0]++;
-
- const Partition& closest_astc = FindClosestASTCPartition(almost_astc);
- EXPECT_EQ(astc, closest_astc);
-}
-
-// Test a partition that was obtained from the reference ASTC encoder. We should
-// be able to match it exactly
-TEST(PartitionTest, TestSpecificPartition) {
- const Partition astc = GetASTCPartition(Footprint::Get10x6(), 3, 557);
- EXPECT_THAT(astc.assignment, ElementsAreArray(std::array<int, 60> {{
- 0, 0, 0, 0, 1, 1, 1, 2, 2, 2,
- 0, 0, 0, 0, 1, 1, 1, 2, 2, 2,
- 0, 0, 0, 0, 1, 1, 1, 2, 2, 2,
- 0, 0, 0, 0, 1, 1, 1, 2, 2, 2,
- 0, 0, 0, 0, 1, 1, 1, 2, 2, 2,
- 0, 0, 0, 0, 1, 1, 1, 2, 2, 2 }}));
-}
-
-// Make sure that when we match against this specific partition, it'll return a
-// partition with the same number of subsets
-TEST(PartitionTest, EstimatedPartitionSubsets) {
- Partition partition = {
- /* footprint = */ Footprint::Get6x6(),
- /* num_parts = */ 2,
- /* partition_id = */ {},
- /* assignment = */ {
- 0, 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1
- }};
-
- const Partition astc = FindClosestASTCPartition(partition);
- EXPECT_THAT(astc.num_parts, Eq(partition.num_parts));
-}
-
-// Make sure that regardless of what partition we match against, it'll return a
-// partition with at most a fewer number of subsets
-TEST(PartitionTest, EstimatedPartitionFewerSubsets) {
- std::mt19937 random(0xdeadbeef);
- auto randUniform = [&random](int max) {
- std::uniform_int_distribution<> dist(0, max - 1);
- return dist(random);
- };
-
- constexpr int kNumFootprints = Footprint::NumValidFootprints();
- const auto kFootprints = std::array<Footprint, kNumFootprints> {{
- Footprint::Get4x4(),
- Footprint::Get5x4(),
- Footprint::Get5x5(),
- Footprint::Get6x5(),
- Footprint::Get6x6(),
- Footprint::Get8x5(),
- Footprint::Get8x6(),
- Footprint::Get8x8(),
- Footprint::Get10x5(),
- Footprint::Get10x6(),
- Footprint::Get10x8(),
- Footprint::Get10x10(),
- Footprint::Get12x10(),
- Footprint::Get12x12()
- }};
-
- constexpr int kNumTests = 200;
- for (int i = 0; i < kNumTests; ++i) {
- const auto& footprint = kFootprints[randUniform(kNumFootprints)];
- const int num_parts = 2 + randUniform(3);
- Partition partition = {
- footprint,
- num_parts,
- /* partition_id = */ {},
- /* assignment = */ std::vector<int>(footprint.NumPixels(), 0)};
-
- for (auto& p : partition.assignment) {
- p = randUniform(num_parts);
- }
-
- const Partition astc = FindClosestASTCPartition(partition);
- EXPECT_THAT(astc.num_parts, Le(partition.num_parts))
- << "Test #" << i << ": "
- << "Selected partition with ID " << astc.partition_id.value();
- }
-}
-
-// Make sure that we generate unique partitions that are close to the
-// candidates.
-TEST(PartitionTest, UniquePartitionResults) {
- Partition partition = {
- /* footprint = */ Footprint::Get6x6(),
- /* num_parts = */ 2,
- /* partition_id = */ {},
- /* assignment = */ {
- 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1
- }};
-
- const auto parts = FindKClosestASTCPartitions(partition, 2);
- EXPECT_THAT(*parts[0], Not(Eq(*parts[1])));
-}
-
-// TODO(google): Verify somehow that the assignment generated from
-// GetASTCPartition actually matches what's in the spec. The selection
-// function was more or less copy/pasted though so it's unclear how to
-// measure that against e.g. the ASTC encoder.
-
-} // namespace
diff --git a/third-party/astc-codec/src/decoder/test/physical_astc_block_test.cc b/third-party/astc-codec/src/decoder/test/physical_astc_block_test.cc
deleted file mode 100644
index 8eafe461..00000000
--- a/third-party/astc-codec/src/decoder/test/physical_astc_block_test.cc
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/physical_astc_block.h"
-#include "src/base/uint128.h"
-
-#include <gtest/gtest.h>
-
-#include <string>
-#include <vector>
-
-using astc_codec::PhysicalASTCBlock;
-using astc_codec::ColorEndpointMode;
-using astc_codec::base::UInt128;
-
-namespace {
-
-static const PhysicalASTCBlock kErrorBlock(UInt128(0));
-
-// Test to make sure that each of the constructors work and that
-// they produce the same block encodings, since the ASTC blocks
-// are little-endian
-TEST(PhysicalASTCBlockTest, TestConstructors) {
- // Little-endian reading of bytes
- PhysicalASTCBlock blk1(0x0000000001FE000173ULL);
- PhysicalASTCBlock blk2(
- std::string("\x73\x01\x00\xFE\x01\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16));
- EXPECT_EQ(blk1.GetBlockBits(), blk2.GetBlockBits());
-}
-
-// Test to see if we properly decode the maximum value that a weight
-// can take in an ASTC block based on the block mode encoding. We test
-// against a valid case and various error cases
-TEST(PhysicalASTCBlockTest, TestWeightRange) {
- PhysicalASTCBlock blk1(0x0000000001FE000173ULL);
- auto weight_range = blk1.WeightRange();
- ASSERT_TRUE(weight_range);
- EXPECT_EQ(weight_range.value(), 7);
-
- // If we flip the high bit then we should have a range of 31,
- // although then we have too many bits and this should error.
- PhysicalASTCBlock blk2(0x0000000001FE000373ULL);
- EXPECT_FALSE(blk2.WeightRange());
-
- // One bit per weight -- range of 1
- PhysicalASTCBlock non_shared_cem(0x4000000000800D44ULL);
- weight_range = non_shared_cem.WeightRange();
- ASSERT_TRUE(weight_range);
- EXPECT_EQ(weight_range.value(), 1);
-
- // Error blocks have no weight range
- EXPECT_FALSE(kErrorBlock.WeightRange());
-}
-
-// Test to see if we properly decode the weight grid width and height
-// in an ASTC block based on the block mode encoding. We test against
-// a valid case and various error cases
-TEST(PhysicalASTCBlockTest, TestWeightDims) {
- PhysicalASTCBlock blk1(0x0000000001FE000173ULL);
- auto weight_dims = blk1.WeightGridDims();
- EXPECT_TRUE(weight_dims);
- EXPECT_EQ(weight_dims.value()[0], 6);
- EXPECT_EQ(weight_dims.value()[1], 5);
-
- // If we flip the high bit then we should have a range of 31,
- // although then we have too many bits for the weight grid
- // and this should error.
- PhysicalASTCBlock blk2(0x0000000001FE000373ULL);
- EXPECT_FALSE(blk2.WeightGridDims());
- EXPECT_EQ(blk2.IsIllegalEncoding().value(),
- "Too many bits required for weight grid");
-
- // Dual plane block with 3x5 weight dims
- PhysicalASTCBlock blk3(0x0000000001FE0005FFULL);
- weight_dims = blk3.WeightGridDims();
- ASSERT_TRUE(weight_dims);
- EXPECT_EQ(weight_dims->at(0), 3);
- EXPECT_EQ(weight_dims->at(1), 5);
-
- // Error blocks shouldn't have any weight dims
- EXPECT_FALSE(kErrorBlock.WeightGridDims());
-
- PhysicalASTCBlock non_shared_cem(0x4000000000800D44ULL);
- weight_dims = non_shared_cem.WeightGridDims();
- ASSERT_TRUE(weight_dims);
- EXPECT_EQ(weight_dims->at(0), 8);
- EXPECT_EQ(weight_dims->at(1), 8);
-}
-
-// Test to see whether or not the presence of a dual-plane bit
-// is decoded properly. Error encodings are tested to *not* return
-// that they have dual planes.
-TEST(PhysicalASTCBlockTest, TestDualPlane) {
- PhysicalASTCBlock blk1(0x0000000001FE000173ULL);
- EXPECT_FALSE(blk1.IsDualPlane());
- EXPECT_FALSE(kErrorBlock.IsDualPlane());
-
- // If we flip the dual plane bit, we will have too many bits
- // for the weight grid and this should error
- PhysicalASTCBlock blk2(0x0000000001FE000573ULL);
- EXPECT_FALSE(blk2.IsDualPlane());
- EXPECT_FALSE(blk2.WeightGridDims());
- EXPECT_EQ(blk2.IsIllegalEncoding().value(),
- "Too many bits required for weight grid");
-
- // A dual plane with 3x5 weight grid should be supported
- PhysicalASTCBlock blk3(0x0000000001FE0005FFULL);
- EXPECT_TRUE(blk3.IsDualPlane());
-
- // If we use the wrong block mode, then a valid block
- // shouldn't have any dual plane
- PhysicalASTCBlock blk4(0x0000000001FE000108ULL);
- EXPECT_FALSE(blk4.IsDualPlane());
- EXPECT_FALSE(blk4.IsIllegalEncoding());
-}
-
-// Make sure that we properly calculate the number of bits used to encode
-// the weight grid. Given error encodings or void extent blocks, this number
-// should be zero
-TEST(PhysicalASTCBlockTest, TestNumWeightBits) {
- // 6x5 single-plane weight grid with 3-bit weights
- // should have 90 bits for the weights.
- PhysicalASTCBlock blk1(0x0000000001FE000173ULL);
- EXPECT_EQ(90, blk1.NumWeightBits());
-
- // Error block has no weight bits
- EXPECT_FALSE(kErrorBlock.NumWeightBits());
-
- // Void extent blocks have no weight bits
- EXPECT_FALSE(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).NumWeightBits());
-
- // If we flip the dual plane bit, we will have too many bits
- // for the weight grid and this should error and return no bits
- PhysicalASTCBlock blk2(0x0000000001FE000573ULL);
- EXPECT_FALSE(blk2.NumWeightBits());
-
- // 3x5 dual-plane weight grid with 3-bit weights
- // should have 90 bits for the weights.
- PhysicalASTCBlock blk3(0x0000000001FE0005FFULL);
- EXPECT_EQ(90, blk3.NumWeightBits());
-}
-
-// Test to make sure that our weight bits start where we expect them to.
-// In other words, make sure that the calculation based on the block mode for
-// where the weight bits start is accurate.
-TEST(PhysicalASTCBlockTest, TestStartWeightBit) {
- EXPECT_EQ(PhysicalASTCBlock(0x4000000000800D44ULL).WeightStartBit(), 64);
-
- // Error blocks have no weight start bit
- EXPECT_FALSE(kErrorBlock.WeightStartBit());
-
- // Void extent blocks have no weight start bit
- EXPECT_FALSE(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).WeightStartBit());
-}
-
-// Test to make sure that we catch various different reasons for error encoding
-// of ASTC blocks, but also that certain encodings aren't errors.
-TEST(PhysicalASTCBlockTest, TestErrorBlocks) {
- // Various valid block modes
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000173ULL).IsIllegalEncoding());
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE0005FFULL).IsIllegalEncoding());
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000108ULL).IsIllegalEncoding());
-
- // This is an error because it uses an invalid block mode
- EXPECT_EQ(kErrorBlock.IsIllegalEncoding().value(), "Reserved block mode");
-
- // This is an error because we have too many weight bits
- PhysicalASTCBlock err_blk(0x0000000001FE000573ULL);
- EXPECT_EQ(err_blk.IsIllegalEncoding().value(),
- "Too many bits required for weight grid");
-
- // This is an error because we have too many weights
- PhysicalASTCBlock err_blk2 = PhysicalASTCBlock(0x0000000001FE0005A8ULL);
- EXPECT_EQ(err_blk2.IsIllegalEncoding().value(), "Too many weights specified");
-
- PhysicalASTCBlock err_blk3 = PhysicalASTCBlock(0x0000000001FE000588ULL);
- EXPECT_EQ(err_blk3.IsIllegalEncoding().value(), "Too many weights specified");
-
- // This is an error because we have too few weights
- PhysicalASTCBlock err_blk4 = PhysicalASTCBlock(0x0000000001FE00002ULL);
- EXPECT_EQ(err_blk4.IsIllegalEncoding().value(),
- "Too few bits required for weight grid");
-
- // Four partitions, dual plane -- should be error
- // 2x2 weight grid, 3 bits per weight
- PhysicalASTCBlock dual_plane_four_parts(0x000000000000001D1FULL);
- EXPECT_FALSE(dual_plane_four_parts.NumPartitions());
- EXPECT_EQ(dual_plane_four_parts.IsIllegalEncoding().value(),
- "Both four partitions and dual plane specified");
-}
-
-// Test to make sure that we properly identify and can manipulate void-extent
-// blocks. These are ASTC blocks that only define a single color for the entire
-// block.
-TEST(PhysicalASTCBlockTest, TestVoidExtentBlocks) {
- // Various valid block modes that aren't void extent blocks
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000173ULL).IsVoidExtent());
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE0005FFULL).IsVoidExtent());
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000108ULL).IsVoidExtent());
-
- // Error block is not a void extent block
- EXPECT_FALSE(kErrorBlock.IsVoidExtent());
-
- // Void extent block is void extent block...
- UInt128 void_extent_encoding(0, 0xFFF8003FFE000DFCULL);
- EXPECT_FALSE(PhysicalASTCBlock(void_extent_encoding).IsIllegalEncoding());
- EXPECT_TRUE(PhysicalASTCBlock(void_extent_encoding).IsVoidExtent());
-
- // If we modify the high 64 bits it shouldn't change anything
- void_extent_encoding |= UInt128(0xdeadbeefdeadbeef, 0);
- EXPECT_FALSE(PhysicalASTCBlock(void_extent_encoding).IsIllegalEncoding());
- EXPECT_TRUE(PhysicalASTCBlock(void_extent_encoding).IsVoidExtent());
-}
-
-TEST(PhysicalASTCBlockTest, TestVoidExtentCoordinates) {
- // The void extent block should have texture coordinates from 0-8191
- auto coords = PhysicalASTCBlock(0xFFF8003FFE000DFCULL).VoidExtentCoords();
- EXPECT_EQ(coords->at(0), 0);
- EXPECT_EQ(coords->at(1), 8191);
- EXPECT_EQ(coords->at(2), 0);
- EXPECT_EQ(coords->at(3), 8191);
-
- // If we set the coords to all 1's then it's still a void extent
- // block, but there aren't any void extent coords.
- EXPECT_FALSE(PhysicalASTCBlock(0xFFFFFFFFFFFFFDFCULL).IsIllegalEncoding());
- EXPECT_TRUE(PhysicalASTCBlock(0xFFFFFFFFFFFFFDFCULL).IsVoidExtent());
- EXPECT_FALSE(PhysicalASTCBlock(0xFFFFFFFFFFFFFDFCULL).VoidExtentCoords());
-
- // If we set the void extent coords to something where the coords are
- // >= each other, then the encoding is illegal.
- EXPECT_TRUE(PhysicalASTCBlock(0x0008004002001DFCULL).IsIllegalEncoding());
- EXPECT_TRUE(PhysicalASTCBlock(0x0007FFC001FFFDFCULL).IsIllegalEncoding());
-}
-
-// Test to see if we can properly identify the number of partitions in a block
-// In particular -- we need to make sure we properly identify single and
-// multi-partition blocks, but also that void extent and error blocks don't
-// return valid numbers of partitions
-TEST(PhysicalASTCBlockTest, TestNumPartitions) {
- // Various valid block modes, but all single partition
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000173ULL).NumPartitions(), 1);
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE0005FFULL).NumPartitions(), 1);
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000108ULL).NumPartitions(), 1);
-
- // Two to four partitions don't have enough bits for color.
- EXPECT_FALSE(PhysicalASTCBlock(0x000000000000000973ULL).NumPartitions());
- EXPECT_FALSE(PhysicalASTCBlock(0x000000000000001173ULL).NumPartitions());
- EXPECT_FALSE(PhysicalASTCBlock(0x000000000000001973ULL).NumPartitions());
-
- // Test against having more than one partition
- PhysicalASTCBlock non_shared_cem(0x4000000000800D44ULL);
- EXPECT_EQ(non_shared_cem.NumPartitions(), 2);
-}
-
-// Test the color endpoint modes specified for how the endpoints are encoded.
-// In particular, test that shared color endpoint modes work for multi-partition
-// blocks and that non-shared color endpoint modes also work.
-TEST(PhysicalASTCBlockTest, TestColorEndpointModes) {
- // Four partitions -- one shared CEM
- const auto blk1 = PhysicalASTCBlock(0x000000000000001961ULL);
- for (int i = 0; i < 4; ++i) {
- EXPECT_EQ(blk1.GetEndpointMode(i), ColorEndpointMode::kLDRLumaDirect);
- }
-
- // Void extent blocks have no endpoint modes
- EXPECT_FALSE(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).GetEndpointMode(0));
-
- // Test out of range partitions
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000173ULL).GetEndpointMode(1));
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000173ULL).GetEndpointMode(-1));
- EXPECT_FALSE(PhysicalASTCBlock(0x0000000001FE000173ULL).GetEndpointMode(100));
-
- // Error blocks have no endpoint modes
- EXPECT_FALSE(kErrorBlock.GetEndpointMode(0));
-
- // Test non-shared CEMs
- PhysicalASTCBlock non_shared_cem(0x4000000000800D44ULL);
- EXPECT_EQ(non_shared_cem.GetEndpointMode(0),
- ColorEndpointMode::kLDRLumaDirect);
- EXPECT_EQ(non_shared_cem.GetEndpointMode(1),
- ColorEndpointMode::kLDRLumaBaseOffset);
-}
-
-// Make sure that if we have more than one partition then we have proper
-// partition IDs (these determine which pixels correspond to which partition)
-TEST(PhysicalASTCBlockTest, TestPartitionID) {
- // Valid partitions
- EXPECT_EQ(PhysicalASTCBlock(0x4000000000FFED44ULL).PartitionID(), 0x3FF);
- EXPECT_EQ(PhysicalASTCBlock(0x4000000000AAAD44ULL).PartitionID(), 0x155);
-
- // Error blocks have no partition IDs
- EXPECT_FALSE(kErrorBlock.PartitionID());
-
- // Void extent blocks have no endpoint modes
- EXPECT_FALSE(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).PartitionID());
-}
-
-// Make sure that we're properly attributing the number of bits associated with
-// the encoded color values.
-TEST(PhysicalASTCBlockTest, TestNumColorBits) {
- // If we're using a direct luma channel, then the number of color bits is 16
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000173ULL).NumColorValues(), 2);
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000173ULL).NumColorBits(), 16);
-
- // Error blocks have nothing
- EXPECT_FALSE(kErrorBlock.NumColorValues());
- EXPECT_FALSE(kErrorBlock.NumColorBits());
-
- // Void extent blocks have four color values and 64 bits of color
- EXPECT_EQ(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).NumColorValues(), 4);
- EXPECT_EQ(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).NumColorBits(), 64);
-}
-
-// Make sure that we're properly decoding the range of values that each of the
-// encoded color values can take
-TEST(PhysicalASTCBlockTest, TestColorValuesRange) {
- // If we're using a direct luma channel, then we use two color values up to
- // a full byte each.
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000173ULL).ColorValuesRange(), 255);
-
- // Error blocks have nothing
- EXPECT_FALSE(kErrorBlock.ColorValuesRange());
-
- // Void extent blocks have four color values and 64 bits of color, so the
- // color range for each is sixteen bits.
- EXPECT_EQ(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).ColorValuesRange(),
- (1 << 16) - 1);
-}
-
-// Test that we know where the color data starts. This is different mostly
-// depending on whether or not the block is single-partition or void extent.
-TEST(PhysicalASTCBlockTest, TestColorStartBits) {
- // Void extent blocks start at bit 64
- EXPECT_EQ(PhysicalASTCBlock(0xFFF8003FFE000DFCULL).ColorStartBit(), 64);
-
- // Error blocks don't start anywhere
- EXPECT_FALSE(kErrorBlock.ColorStartBit());
-
- // Single partition blocks start at bit 17
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000173ULL).ColorStartBit(), 17);
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE0005FFULL).ColorStartBit(), 17);
- EXPECT_EQ(PhysicalASTCBlock(0x0000000001FE000108ULL).ColorStartBit(), 17);
-
- // Multi-partition blocks start at bit 29
- EXPECT_EQ(PhysicalASTCBlock(0x4000000000FFED44ULL).ColorStartBit(), 29);
- EXPECT_EQ(PhysicalASTCBlock(0x4000000000AAAD44ULL).ColorStartBit(), 29);
-}
-
-} // namespace
diff --git a/third-party/astc-codec/src/decoder/test/quantization_test.cc b/third-party/astc-codec/src/decoder/test/quantization_test.cc
deleted file mode 100644
index f882876e..00000000
--- a/third-party/astc-codec/src/decoder/test/quantization_test.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/quantization.h"
-#include "src/decoder/integer_sequence_codec.h"
-
-#include <gtest/gtest.h>
-
-#include <functional>
-#include <string>
-#include <vector>
-
-namespace astc_codec {
-
-namespace {
-
-// Make sure that we never exceed the maximum range that we pass in.
-TEST(QuantizationTest, TestQuantizeMaxRange) {
- for (int i = kEndpointRangeMinValue; i < 256; ++i) {
- EXPECT_LE(QuantizeCEValueToRange(255, i), i);
- }
-
- for (int i = 1; i < kWeightRangeMaxValue; ++i) {
- EXPECT_LE(QuantizeWeightToRange(64, i), i);
- }
-}
-
-// Make sure that whenever we unquantize and requantize a value we get back
-// what we started with.
-TEST(QuantizationTest, TestReversibility) {
- for (auto itr = ISERangeBegin(); itr != ISERangeEnd(); itr++) {
- const int range = *itr;
- if (range <= kWeightRangeMaxValue) {
- for (int j = 0; j <= range; ++j) {
- const int q = UnquantizeWeightFromRange(j, range);
- EXPECT_EQ(QuantizeWeightToRange(q, range), j);
- }
- }
-
- if (range >= kEndpointRangeMinValue) {
- for (int j = 0; j <= range; ++j) {
- const int q = UnquantizeCEValueFromRange(j, range);
- EXPECT_EQ(QuantizeCEValueToRange(q, range), j);
- }
- }
- }
-}
-
-// Make sure that whenever we quantize a non-maximal value it gets sent to the
-// proper range
-TEST(QuantizationTest, TestQuantizationRange) {
- for (auto itr = ISERangeBegin(); itr != ISERangeEnd(); itr++) {
- const int range = *itr;
- if (range >= kEndpointRangeMinValue) {
- EXPECT_LE(QuantizeCEValueToRange(0, range), range);
- EXPECT_LE(QuantizeCEValueToRange(4, range), range);
- EXPECT_LE(QuantizeCEValueToRange(15, range), range);
- EXPECT_LE(QuantizeCEValueToRange(22, range), range);
- EXPECT_LE(QuantizeCEValueToRange(66, range), range);
- EXPECT_LE(QuantizeCEValueToRange(91, range), range);
- EXPECT_LE(QuantizeCEValueToRange(126, range), range);
- }
-
- if (range <= kWeightRangeMaxValue) {
- EXPECT_LE(QuantizeWeightToRange(0, range), range);
- EXPECT_LE(QuantizeWeightToRange(4, range), range);
- EXPECT_LE(QuantizeWeightToRange(15, range), range);
- EXPECT_LE(QuantizeWeightToRange(22, range), range);
- }
- }
-}
-
-// Make sure that whenever we unquantize a value it remains within [0, 255]
-TEST(QuantizationTest, TestUnquantizationRange) {
- EXPECT_LT(UnquantizeCEValueFromRange(2, 7), 256);
- EXPECT_LT(UnquantizeCEValueFromRange(7, 7), 256);
- EXPECT_LT(UnquantizeCEValueFromRange(39, 63), 256);
- EXPECT_LT(UnquantizeCEValueFromRange(66, 79), 256);
- EXPECT_LT(UnquantizeCEValueFromRange(91, 191), 256);
- EXPECT_LT(UnquantizeCEValueFromRange(126, 255), 256);
- EXPECT_LT(UnquantizeCEValueFromRange(255, 255), 256);
-
- EXPECT_LE(UnquantizeWeightFromRange(0, 1), 64);
- EXPECT_LE(UnquantizeWeightFromRange(2, 7), 64);
- EXPECT_LE(UnquantizeWeightFromRange(7, 7), 64);
- EXPECT_LE(UnquantizeWeightFromRange(29, 31), 64);
-}
-
-// When we quantize a value, it should use the largest quantization range that
-// does not exceed the desired range.
-TEST(QuantizationTest, TestUpperBoundRanges) {
- auto expected_range_itr = ISERangeBegin();
- for (int desired_range = 1; desired_range < 256; ++desired_range) {
- if (desired_range == *(expected_range_itr + 1)) {
- ++expected_range_itr;
- }
- const int expected_range = *expected_range_itr;
- ASSERT_LE(expected_range, desired_range);
-
- if (desired_range >= kEndpointRangeMinValue) {
- EXPECT_EQ(QuantizeCEValueToRange(0, desired_range),
- QuantizeCEValueToRange(0, expected_range));
-
- EXPECT_EQ(QuantizeCEValueToRange(208, desired_range),
- QuantizeCEValueToRange(208, expected_range));
-
- EXPECT_EQ(QuantizeCEValueToRange(173, desired_range),
- QuantizeCEValueToRange(173, expected_range));
-
- EXPECT_EQ(QuantizeCEValueToRange(13, desired_range),
- QuantizeCEValueToRange(13, expected_range));
-
- EXPECT_EQ(QuantizeCEValueToRange(255, desired_range),
- QuantizeCEValueToRange(255, expected_range));
- }
-
- if (desired_range <= kWeightRangeMaxValue) {
- EXPECT_EQ(QuantizeWeightToRange(0, desired_range),
- QuantizeWeightToRange(0, expected_range));
-
- EXPECT_EQ(QuantizeWeightToRange(63, desired_range),
- QuantizeWeightToRange(63, expected_range));
-
- EXPECT_EQ(QuantizeWeightToRange(12, desired_range),
- QuantizeWeightToRange(12, expected_range));
-
- EXPECT_EQ(QuantizeWeightToRange(23, desired_range),
- QuantizeWeightToRange(23, expected_range));
- }
- }
-
- // Make sure that we covered all the possible ranges
- ASSERT_EQ(std::next(expected_range_itr), ISERangeEnd());
-}
-
-// Make sure that quantizing to the largest range is the identity function.
-TEST(QuantizationTest, TestIdentity) {
- for (int i = 0; i < 256; ++i) {
- EXPECT_EQ(QuantizeCEValueToRange(i, 255), i);
- }
-
- // Note: This doesn't apply to weights since there's a weird hack to convert
- // values from [0, 31] to [0, 64].
-}
-
-// Make sure that bit quantization is monotonic with respect to the input,
-// since quantizing and dequantizing bits is a matter of truncation and bit
-// replication
-TEST(QuantizationTest, TestMonotonicBitPacking) {
- for (int num_bits = 3; num_bits < 8; ++num_bits) {
- const int range = (1 << num_bits) - 1;
- int last_quant_val = -1;
- for (int i = 0; i < 256; ++i) {
- const int quant_val = QuantizeCEValueToRange(i, range);
- EXPECT_LE(last_quant_val, quant_val);
- last_quant_val = quant_val;
- }
-
- // Also expect the last quantization val to be equal to the range
- EXPECT_EQ(last_quant_val, range);
-
- if (range <= kWeightRangeMaxValue) {
- last_quant_val = -1;
- for (int i = 0; i <= 64; ++i) {
- const int quant_val = QuantizeWeightToRange(i, range);
- EXPECT_LE(last_quant_val, quant_val);
- last_quant_val = quant_val;
- }
- EXPECT_EQ(last_quant_val, range);
- }
- }
-}
-
-// Make sure that bit quantization reflects that quantized values below the bit
-// replication threshold get mapped to zero
-TEST(QuantizationTest, TestSmallBitPacking) {
- for (int num_bits = 1; num_bits <= 8; ++num_bits) {
- const int range = (1 << num_bits) - 1;
-
- // The largest number that should map to zero is one less than half of the
- // smallest representation w.r.t. range. For example: if we have a range
- // of 7, it means that we have 3 total bits abc for quantized values. If we
- // unquantize to 8 bits, it means that our resulting value will be abcabcab.
- // Hence, we map 000 to 0 and 001 to 0b00100100 = 36. The earliest value
- // that should not map to zero with three bits is therefore 0b00001111 = 15.
- // This ends up being (1 << (8 - 3 - 1)) - 1. We don't use 0b00011111 = 31
- // because this would "round up" to 1 during quantization. This value is not
- // necessarily the largest, but it is the largest that we can *guarantee*
- // should map to zero.
-
- if (range >= kEndpointRangeMinValue) {
- constexpr int cev_bits = 8;
- const int half_max_quant_bits = std::max(0, cev_bits - num_bits - 1);
- const int largest_cev_to_zero = (1 << half_max_quant_bits) - 1;
- EXPECT_EQ(QuantizeCEValueToRange(largest_cev_to_zero, range), 0)
- << " Largest CEV to zero: " << largest_cev_to_zero
- << " Range: " << range;
- }
-
- if (range <= kWeightRangeMaxValue) {
- constexpr int weight_bits = 6;
- const int half_max_quant_bits = std::max(0, weight_bits - num_bits - 1);
- const int largest_weight_to_zero = (1 << half_max_quant_bits) - 1;
- EXPECT_EQ(QuantizeWeightToRange(largest_weight_to_zero, range), 0)
- << " Largest weight to zero: " << largest_weight_to_zero
- << " Range: " << range;
- }
- }
-}
-
-// Test specific quint and trit weight encodings with values that were obtained
-// using the reference ASTC codec.
-TEST(QuantizationTest, TestSpecificQuintTritPackings) {
- std::vector<int> vals = { 4, 6, 4, 6, 7, 5, 7, 5 };
- std::vector<int> quantized;
-
- // Test a quint packing
- std::transform(
- vals.begin(), vals.end(), std::back_inserter(quantized),
- std::bind(UnquantizeWeightFromRange, std::placeholders::_1, 9));
- const std::vector<int> quintExpected = {14, 21, 14, 21, 43, 50, 43, 50 };
- EXPECT_EQ(quantized, quintExpected);
-
- // Test a trit packing
- std::transform(
- vals.begin(), vals.end(), quantized.begin(),
- std::bind(UnquantizeWeightFromRange, std::placeholders::_1, 11));
- const std::vector<int> tritExpected = { 5, 23, 5, 23, 41, 59, 41, 59 };
- EXPECT_EQ(quantized, tritExpected);
-}
-
-// Make sure that we properly die when we pass in values below the minimum
-// allowed ranges for our quantization intervals.
-TEST(QuantizationDeathTest, TestInvalidMinRange) {
- for (int i = 0; i < kEndpointRangeMinValue; ++i) {
- EXPECT_DEBUG_DEATH(QuantizeCEValueToRange(0, i), "");
- EXPECT_DEBUG_DEATH(UnquantizeCEValueFromRange(0, i), "");
- }
-
- EXPECT_DEBUG_DEATH(QuantizeWeightToRange(0, 0), "");
- EXPECT_DEBUG_DEATH(UnquantizeWeightFromRange(0, 0), "");
-}
-
-// Make sure that we properly die when we pass in bogus values.
-TEST(QuantizationDeathTest, TestOutOfRange) {
- EXPECT_DEBUG_DEATH(QuantizeCEValueToRange(-1, 10), "");
- EXPECT_DEBUG_DEATH(QuantizeCEValueToRange(256, 7), "");
- EXPECT_DEBUG_DEATH(QuantizeCEValueToRange(10000, 17), "");
-
- EXPECT_DEBUG_DEATH(UnquantizeCEValueFromRange(-1, 10), "");
- EXPECT_DEBUG_DEATH(UnquantizeCEValueFromRange(8, 7), "");
- EXPECT_DEBUG_DEATH(UnquantizeCEValueFromRange(-1000, 17), "");
-
- EXPECT_DEBUG_DEATH(QuantizeCEValueToRange(0, -7), "");
- EXPECT_DEBUG_DEATH(UnquantizeCEValueFromRange(0, -17), "");
-
- EXPECT_DEBUG_DEATH(QuantizeCEValueToRange(0, 257), "");
- EXPECT_DEBUG_DEATH(UnquantizeCEValueFromRange(0, 256), "");
-
- EXPECT_DEBUG_DEATH(QuantizeWeightToRange(-1, 10), "");
- EXPECT_DEBUG_DEATH(QuantizeWeightToRange(256, 7), "");
- EXPECT_DEBUG_DEATH(QuantizeWeightToRange(10000, 17), "");
-
- EXPECT_DEBUG_DEATH(UnquantizeWeightFromRange(-1, 10), "");
- EXPECT_DEBUG_DEATH(UnquantizeWeightFromRange(8, 7), "");
- EXPECT_DEBUG_DEATH(UnquantizeWeightFromRange(-1000, 17), "");
-
- EXPECT_DEBUG_DEATH(QuantizeWeightToRange(0, -7), "");
- EXPECT_DEBUG_DEATH(UnquantizeWeightFromRange(0, -17), "");
-
- EXPECT_DEBUG_DEATH(QuantizeWeightToRange(0, 32), "");
- EXPECT_DEBUG_DEATH(UnquantizeWeightFromRange(0, 64), "");
-}
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/test/weight_infill_test.cc b/third-party/astc-codec/src/decoder/test/weight_infill_test.cc
deleted file mode 100644
index 79c77455..00000000
--- a/third-party/astc-codec/src/decoder/test/weight_infill_test.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/weight_infill.h"
-#include "src/decoder/footprint.h"
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-namespace astc_codec {
-
-namespace {
-
-// Make sure that the physical size of the bit representations for certain
-// dimensions of weight grids matches our expectations
-TEST(ASTCWeightInfillTest, TestGetBitCount) {
- // Bit encodings
- EXPECT_EQ(32, CountBitsForWeights(4, 4, 3));
- EXPECT_EQ(48, CountBitsForWeights(4, 4, 7));
- EXPECT_EQ(24, CountBitsForWeights(2, 4, 7));
- EXPECT_EQ(8, CountBitsForWeights(2, 4, 1));
-
- // Trit encodings
- EXPECT_EQ(32, CountBitsForWeights(4, 5, 2));
- EXPECT_EQ(26, CountBitsForWeights(4, 4, 2));
- EXPECT_EQ(52, CountBitsForWeights(4, 5, 5));
- EXPECT_EQ(42, CountBitsForWeights(4, 4, 5));
-
- // Quint encodings
- EXPECT_EQ(21, CountBitsForWeights(3, 3, 4));
- EXPECT_EQ(38, CountBitsForWeights(4, 4, 4));
- EXPECT_EQ(49, CountBitsForWeights(3, 7, 4));
- EXPECT_EQ(52, CountBitsForWeights(4, 3, 19));
- EXPECT_EQ(70, CountBitsForWeights(4, 4, 19));
-}
-
-// Make sure that we bilerp our weights properly
-TEST(ASTCWeightInfillTest, TestInfillBilerp) {
- std::vector<int> weights = InfillWeights(
- {{ 1, 3, 5, 3, 5, 7, 5, 7, 9 }}, Footprint::Get5x5(), 3, 3);
-
- std::vector<int> expected_weights = {
- 1, 2, 3, 4, 5,
- 2, 3, 4, 5, 6,
- 3, 4, 5, 6, 7,
- 4, 5, 6, 7, 8,
- 5, 6, 7, 8, 9 };
-
- ASSERT_EQ(weights.size(), expected_weights.size());
- for (int i = 0; i < weights.size(); ++i) {
- EXPECT_EQ(weights[i], expected_weights[i]);
- }
-}
-
-} // namespace
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.astc b/third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.astc
deleted file mode 100644
index 0dd080b1..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.bmp b/third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.bmp
deleted file mode 100644
index 32412b3e..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_4x4.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.astc b/third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.astc
deleted file mode 100644
index 2831c90e..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.bmp b/third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.bmp
deleted file mode 100644
index 95b0186a..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_5x5.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.astc b/third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.astc
deleted file mode 100644
index b2cc9c2d..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.bmp b/third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.bmp
deleted file mode 100644
index 796812e2..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_6x6.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.astc b/third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.astc
deleted file mode 100644
index a8805f28..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.bmp b/third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.bmp
deleted file mode 100644
index 8f92698c..00000000
--- a/third-party/astc-codec/src/decoder/testdata/atlas_small_8x8.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkerboard.astc b/third-party/astc-codec/src/decoder/testdata/checkerboard.astc
deleted file mode 100644
index 79acdca3..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkerboard.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_10.astc b/third-party/astc-codec/src/decoder/testdata/checkered_10.astc
deleted file mode 100644
index e3b19657..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_10.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_11.astc b/third-party/astc-codec/src/decoder/testdata/checkered_11.astc
deleted file mode 100644
index c80c6a46..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_11.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_12.astc b/third-party/astc-codec/src/decoder/testdata/checkered_12.astc
deleted file mode 100644
index a82583a9..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_12.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_4.astc b/third-party/astc-codec/src/decoder/testdata/checkered_4.astc
deleted file mode 100644
index ac607164..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_4.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_5.astc b/third-party/astc-codec/src/decoder/testdata/checkered_5.astc
deleted file mode 100644
index 0389c53d..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_5.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_6.astc b/third-party/astc-codec/src/decoder/testdata/checkered_6.astc
deleted file mode 100644
index 210dd340..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_6.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_7.astc b/third-party/astc-codec/src/decoder/testdata/checkered_7.astc
deleted file mode 100644
index 8ea10f84..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_7.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_8.astc b/third-party/astc-codec/src/decoder/testdata/checkered_8.astc
deleted file mode 100644
index 3708882d..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_8.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/checkered_9.astc b/third-party/astc-codec/src/decoder/testdata/checkered_9.astc
deleted file mode 100644
index b5c962a1..00000000
--- a/third-party/astc-codec/src/decoder/testdata/checkered_9.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x10.astc b/third-party/astc-codec/src/decoder/testdata/footprint_10x10.astc
deleted file mode 100644
index 6799cd08..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x10.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x10.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_10x10.bmp
deleted file mode 100644
index 7ded6adf..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x10.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x5.astc b/third-party/astc-codec/src/decoder/testdata/footprint_10x5.astc
deleted file mode 100644
index cbfe4f26..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x5.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x5.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_10x5.bmp
deleted file mode 100644
index 68202f85..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x5.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x6.astc b/third-party/astc-codec/src/decoder/testdata/footprint_10x6.astc
deleted file mode 100644
index 53e37b4a..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x6.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x6.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_10x6.bmp
deleted file mode 100644
index 3dffe72e..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x6.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x8.astc b/third-party/astc-codec/src/decoder/testdata/footprint_10x8.astc
deleted file mode 100644
index b9613e58..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x8.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_10x8.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_10x8.bmp
deleted file mode 100644
index b7d75f73..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_10x8.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_12x10.astc b/third-party/astc-codec/src/decoder/testdata/footprint_12x10.astc
deleted file mode 100644
index 54f59193..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_12x10.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_12x10.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_12x10.bmp
deleted file mode 100644
index 2007a3dc..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_12x10.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_12x12.astc b/third-party/astc-codec/src/decoder/testdata/footprint_12x12.astc
deleted file mode 100644
index d94d0a6c..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_12x12.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_12x12.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_12x12.bmp
deleted file mode 100644
index 57e24a22..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_12x12.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_4x4.astc b/third-party/astc-codec/src/decoder/testdata/footprint_4x4.astc
deleted file mode 100644
index fdf3cd6b..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_4x4.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_4x4.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_4x4.bmp
deleted file mode 100644
index fcb4e077..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_4x4.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_5x4.astc b/third-party/astc-codec/src/decoder/testdata/footprint_5x4.astc
deleted file mode 100644
index 06830594..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_5x4.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_5x4.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_5x4.bmp
deleted file mode 100644
index 9cae5f93..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_5x4.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_5x5.astc b/third-party/astc-codec/src/decoder/testdata/footprint_5x5.astc
deleted file mode 100644
index 03c3395a..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_5x5.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_5x5.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_5x5.bmp
deleted file mode 100644
index c5ddeec4..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_5x5.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_6x5.astc b/third-party/astc-codec/src/decoder/testdata/footprint_6x5.astc
deleted file mode 100644
index d0d455d0..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_6x5.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_6x5.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_6x5.bmp
deleted file mode 100644
index 94a005dc..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_6x5.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_6x6.astc b/third-party/astc-codec/src/decoder/testdata/footprint_6x6.astc
deleted file mode 100644
index 47e038ef..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_6x6.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_6x6.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_6x6.bmp
deleted file mode 100644
index fb1f41c4..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_6x6.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_8x5.astc b/third-party/astc-codec/src/decoder/testdata/footprint_8x5.astc
deleted file mode 100644
index 4ef49d65..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_8x5.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_8x5.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_8x5.bmp
deleted file mode 100644
index 6d4f6093..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_8x5.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_8x6.astc b/third-party/astc-codec/src/decoder/testdata/footprint_8x6.astc
deleted file mode 100644
index 11355095..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_8x6.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_8x6.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_8x6.bmp
deleted file mode 100644
index 35e71219..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_8x6.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_8x8.astc b/third-party/astc-codec/src/decoder/testdata/footprint_8x8.astc
deleted file mode 100644
index bdeb9c9b..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_8x8.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/footprint_8x8.bmp b/third-party/astc-codec/src/decoder/testdata/footprint_8x8.bmp
deleted file mode 100644
index 3b3a1c89..00000000
--- a/third-party/astc-codec/src/decoder/testdata/footprint_8x8.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_12x12.astc b/third-party/astc-codec/src/decoder/testdata/rgb_12x12.astc
deleted file mode 100644
index cc0fc3d3..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_12x12.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_12x12.bmp b/third-party/astc-codec/src/decoder/testdata/rgb_12x12.bmp
deleted file mode 100644
index 50538ded..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_12x12.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_4x4.astc b/third-party/astc-codec/src/decoder/testdata/rgb_4x4.astc
deleted file mode 100644
index 84527d3a..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_4x4.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_4x4.bmp b/third-party/astc-codec/src/decoder/testdata/rgb_4x4.bmp
deleted file mode 100644
index fae4f919..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_4x4.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_5x4.astc b/third-party/astc-codec/src/decoder/testdata/rgb_5x4.astc
deleted file mode 100644
index 377938de..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_5x4.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_5x4.bmp b/third-party/astc-codec/src/decoder/testdata/rgb_5x4.bmp
deleted file mode 100644
index a0c1fdbb..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_5x4.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_6x6.astc b/third-party/astc-codec/src/decoder/testdata/rgb_6x6.astc
deleted file mode 100644
index 8a70c0fd..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_6x6.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_6x6.bmp b/third-party/astc-codec/src/decoder/testdata/rgb_6x6.bmp
deleted file mode 100644
index e1a5dcd8..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_6x6.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_8x8.astc b/third-party/astc-codec/src/decoder/testdata/rgb_8x8.astc
deleted file mode 100644
index 1bca381d..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_8x8.astc
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/testdata/rgb_8x8.bmp b/third-party/astc-codec/src/decoder/testdata/rgb_8x8.bmp
deleted file mode 100644
index 12b6eb24..00000000
--- a/third-party/astc-codec/src/decoder/testdata/rgb_8x8.bmp
+++ /dev/null
Binary files differ
diff --git a/third-party/astc-codec/src/decoder/tools/astc_inspector_cli.cc b/third-party/astc-codec/src/decoder/tools/astc_inspector_cli.cc
deleted file mode 100644
index 105f5749..00000000
--- a/third-party/astc-codec/src/decoder/tools/astc_inspector_cli.cc
+++ /dev/null
@@ -1,785 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// astc_inspector_cli collects the various statistics of a stream of ASTC data
-// stored in an ASTC file.
-//
-// Example usage:
-// To dump statistics about an ASTC file, use:
-// astc_inspector_cli <filename>
-//
-// To dump statistics on a specific block in an ASTC file, use:
-// astc_inspector_cli <filename> <number>
-
-#include <algorithm>
-#include <array>
-#include <fstream>
-#include <functional>
-#include <iomanip>
-#include <iostream>
-#include <memory>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include "src/base/string_utils.h"
-#include "src/decoder/astc_file.h"
-#include "src/decoder/endpoint_codec.h"
-#include "src/decoder/intermediate_astc_block.h"
-#include "src/decoder/partition.h"
-#include "src/decoder/quantization.h"
-#include "src/decoder/weight_infill.h"
-
-using astc_codec::ASTCFile;
-using astc_codec::ColorEndpointMode;
-using astc_codec::IntermediateBlockData;
-using astc_codec::PhysicalASTCBlock;
-using astc_codec::RgbaColor;
-using astc_codec::VoidExtentData;
-using astc_codec::base::Optional;
-
-namespace {
-
-constexpr int kNumEndpointModes =
- static_cast<int>(ColorEndpointMode::kNumColorEndpointModes);
-constexpr std::array<const char*, kNumEndpointModes> kModeStrings {{
- "kLDRLumaDirect", "kLDRLumaBaseOffset", "kHDRLumaLargeRange",
- "kHDRLumaSmallRange", "kLDRLumaAlphaDirect", "kLDRLumaAlphaBaseOffset",
- "kLDRRGBBaseScale", "kHDRRGBBaseScale", "kLDRRGBDirect",
- "kLDRRGBBaseOffset", "kLDRRGBBaseScaleTwoA", "kHDRRGBDirect",
- "kLDRRGBADirect", "kLDRRGBABaseOffset", "kHDRRGBDirectLDRAlpha",
- "kHDRRGBDirectHDRAlpha" }};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// A generic stat that should be tracked via an instance of ASTCFileStats.
-class Stat {
- public:
- explicit Stat(const std::vector<IntermediateBlockData>* blocks, size_t total)
- : blocks_(blocks), total_(total) { }
- virtual ~Stat() { }
-
- virtual std::ostream& PrintToStream(std::ostream& out) const = 0;
-
- protected:
- // Utility function to iterate over all of the blocks that are not void-extent
- // blocks. FoldFn optionally allows a value to accumulate. It should be of the
- // type:
- // (const IntermediateBlockData&, T x) -> T
- template<typename T, typename FoldFn>
- T IterateBlocks(T initial, FoldFn f) const {
- T result = initial;
- for (const auto& block : *blocks_) {
- result = f(block, std::move(result));
- }
- return result;
- }
-
- size_t NumBlocks() const { return total_; }
-
- private:
- const std::vector<IntermediateBlockData>* const blocks_;
- const size_t total_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Computes the number of void extent blocks.
-class VoidExtentCount : public Stat {
- public:
- VoidExtentCount(const std::vector<IntermediateBlockData>* blocks,
- size_t total, std::string description)
- : Stat(blocks, total), description_(std::move(description)),
- count_(total - blocks->size()) { }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- return out << description_ << ": " << count_
- << " (" << (count_ * 100 / NumBlocks()) << "%)" << std::endl;
- };
-
- private:
- const std::string description_;
- const size_t count_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Computes a per-block stat and reports it as an average over all blocks.
-class PerBlockAverage : public Stat {
- public:
- PerBlockAverage(const std::vector<IntermediateBlockData>* blocks,
- size_t total, std::string description,
- const std::function<int(const IntermediateBlockData&)> &fn)
- : Stat(blocks, total),
- description_(std::move(description)) {
- int sum = 0;
- size_t count = 0;
- for (const auto& block : *blocks) {
- sum += fn(block);
- ++count;
- }
- average_ = sum / count;
- }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- return out << description_ << ": " << average_ << std::endl;
- }
-
- private:
- size_t average_;
- std::string description_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Computes a per-block true or false value and reports how many blocks return
-// true with a percentage of total blocks.
-class PerBlockPredicate : public Stat {
- public:
- PerBlockPredicate(const std::vector<IntermediateBlockData>* blocks,
- size_t total, std::string description,
- const std::function<bool(const IntermediateBlockData&)> &fn)
- : Stat(blocks, total),
- description_(std::move(description)),
- count_(std::count_if(blocks->begin(), blocks->end(), fn)) { }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- return out << description_ << ": " << count_
- << " (" << (count_ * 100 / NumBlocks()) << "%)" << std::endl;
- };
-
- private:
- const std::string description_;
- const size_t count_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Returns a histogram of the number of occurrences of each endpoint mode in
-// the list of blocks. Note, due to multi-subset blocks, the sum of these
-// values will not match the total number of blocks.
-class ModeCountsStat : public Stat {
- public:
- explicit ModeCountsStat(const std::vector<IntermediateBlockData>* blocks,
- size_t total)
- : Stat(blocks, total),
- mode_counts_(IterateBlocks<ModeArray>(
- {}, [](const IntermediateBlockData& data, ModeArray&& m) {
- auto result = m;
- for (const auto& ep : data.endpoints) {
- result[static_cast<int>(ep.mode)]++;
- }
- return result;
- })) { }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- const size_t total_modes_used =
- std::accumulate(mode_counts_.begin(), mode_counts_.end(), 0);
-
- out << "Endpoint modes used: " << std::endl;
- for (size_t i = 0; i < kNumEndpointModes; ++i) {
- out << " ";
- out << std::setw(30) << std::left << std::setfill('.') << kModeStrings[i];
- out << std::setw(8) << std::right << std::setfill('.') << mode_counts_[i];
-
- std::stringstream pct;
- pct << " (" << (mode_counts_[i] * 100 / total_modes_used) << "%)";
-
- out << std::setw(6) << std::right << std::setfill(' ') << pct.str();
- out << std::endl;
- }
-
- return out;
- }
-
- private:
- using ModeArray = std::array<int, kNumEndpointModes>;
- const ModeArray mode_counts_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Counts the number of unique endpoints used across all blocks.
-class UniqueEndpointsCount : public Stat {
- public:
- explicit UniqueEndpointsCount(
- const std::vector<IntermediateBlockData>* blocks, size_t total)
- : Stat(blocks, total),
- unique_endpoints_(IterateBlocks<UniqueEndpointSet>(
- UniqueEndpointSet(),
- [](const IntermediateBlockData& data, UniqueEndpointSet&& eps) {
- UniqueEndpointSet result(eps);
- for (const auto& ep : data.endpoints) {
- RgbaColor ep_one, ep_two;
- DecodeColorsForMode(ep.colors, data.endpoint_range.value(),
- ep.mode, &ep_one, &ep_two);
- result.insert(PackEndpoint(ep_one));
- result.insert(PackEndpoint(ep_two));
- }
- return result;
- })) { }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- out << "Num unique endpoints: " << unique_endpoints_.size() << std::endl;
- return out;
- }
-
- private:
- static uint32_t PackEndpoint(const RgbaColor& color) {
- uint32_t result = 0;
- for (const int& c : color) {
- constexpr int kSaturatedChannelValue = 0xFF;
- assert(c >= 0);
- assert(c <= kSaturatedChannelValue);
- result <<= 8;
- result |= c;
- }
- return result;
- }
-
- using UniqueEndpointSet = std::unordered_set<uint32_t>;
- const UniqueEndpointSet unique_endpoints_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Computes a histogram of the number of occurrences of 1-4 subset partitions.
-class PartitionCountStat : public Stat {
- public:
- explicit PartitionCountStat(const std::vector<IntermediateBlockData>* blocks,
- size_t total)
- : Stat(blocks, total)
- , part_counts_(IterateBlocks<PartCount>(
- {}, [](const IntermediateBlockData& data, PartCount&& m) {
- PartCount result = m;
- result[data.endpoints.size() - 1]++;
- return result;
- })) { }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- out << "Num partitions used: " << std::endl;
- for (size_t i = 0; i < part_counts_.size(); ++i) {
- out << " " << i + 1 << ": " << part_counts_[i] << std::endl;
- }
- return out;
- }
-
- private:
- using PartCount = std::array<int, 4>;
- const PartCount part_counts_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// For each block that uses dual-plane mode, computes and stores the dual-plane
-// channels in a vector. Outputs the number of each channel used across all
-// blocks
-class DualChannelStat : public Stat {
- private:
- static constexpr auto kNumDualPlaneChannels =
- std::tuple_size<astc_codec::Endpoint>::value;
- using CountsArray = std::array<int, kNumDualPlaneChannels>;
-
- public:
- explicit DualChannelStat(const std::vector<IntermediateBlockData>* blocks,
- size_t total)
- : Stat(blocks, total),
- dual_channels_(IterateBlocks(
- std::vector<int>(),
- [](const IntermediateBlockData& data, std::vector<int>&& input) {
- auto result = input;
- if (data.dual_plane_channel) {
- result.push_back(data.dual_plane_channel.value());
- }
- return result;
- })) { }
-
- std::ostream& PrintToStream(std::ostream& out) const override {
- // Similar to the number of partitions, the number of dual plane blocks
- // can be determined by parsing the next four fields and summing them.
- const int num_dual_plane_blocks = dual_channels_.size();
- out << "Number of dual-plane blocks: " << num_dual_plane_blocks
- << " (" << (num_dual_plane_blocks * 100) / NumBlocks() << "%)"
- << std::endl;
-
- CountsArray counts = GetCounts();
- assert(counts.size() == kNumDualPlaneChannels);
-
- for (size_t i = 0; i < counts.size(); ++i) {
- out << " " << i << ": " << counts[i] << std::endl;
- }
- return out;
- }
-
- private:
- CountsArray GetCounts() const {
- CountsArray counts;
- for (size_t i = 0; i < kNumDualPlaneChannels; ++i) {
- counts[i] =
- std::count_if(dual_channels_.begin(), dual_channels_.end(),
- [i](int channel) { return i == channel; });
- }
- return counts;
- }
-
- const std::vector<int> dual_channels_;
-};
-
-
-// Stores the intermediate block representations of the blocks associated with
-// an ASTCFile. Also provides various facilities for extracting aggregate data
-// from these blocks.
-class ASTCFileStats {
- public:
- explicit ASTCFileStats(const std::unique_ptr<ASTCFile>& astc_file) {
- const size_t total = astc_file->NumBlocks();
-
- for (size_t block_idx = 0; block_idx < astc_file->NumBlocks(); ++block_idx) {
- const PhysicalASTCBlock pb = astc_file->GetBlock(block_idx);
- assert(!pb.IsIllegalEncoding());
- if (pb.IsIllegalEncoding()) {
- std::cerr << "WARNING: Block " << block_idx << " has illegal encoding." << std::endl;
- continue;
- }
-
- if (!pb.IsVoidExtent()) {
- Optional<IntermediateBlockData> block = UnpackIntermediateBlock(pb);
- if (!block) {
- std::cerr << "WARNING: Block " << block_idx << " failed to unpack." << std::endl;
- continue;
- }
-
- blocks_.push_back(block.value());
- }
- }
-
- stats_.emplace_back(new UniqueEndpointsCount(&blocks_, total));
- stats_.emplace_back(new VoidExtentCount(
- &blocks_, total, "Num void extent blocks"));
-
- stats_.emplace_back(new PerBlockAverage(
- &blocks_, total, "Average weight range",
- [](const IntermediateBlockData& b) { return b.weight_range; }));
-
- stats_.emplace_back(new PerBlockAverage(
- &blocks_, total, "Average number of weights",
- [](const IntermediateBlockData& b) { return b.weights.size(); }));
-
- stats_.emplace_back(new PerBlockPredicate(
- &blocks_, total, "Num blocks that use blue contract mode",
- [](const IntermediateBlockData& block) {
- for (const auto& ep : block.endpoints) {
- if (UsesBlueContract(
- block.endpoint_range.valueOr(255), ep.mode, ep.colors)) {
- return true;
- }
- }
-
- return false;
- }));
-
- stats_.emplace_back(new ModeCountsStat(&blocks_, total));
-
- stats_.emplace_back(new PerBlockPredicate(
- &blocks_, total, "Num multi-part blocks",
- [](const IntermediateBlockData& block) {
- return block.endpoints.size() > 1;
- }));
- stats_.emplace_back(new PartitionCountStat(&blocks_, total));
-
- stats_.emplace_back(new DualChannelStat(&blocks_, total));
- }
-
- // Returns a sorted list of pairs of the form (part_id, count) where the
- // |part_id| is the partition ID used for 2-subset blocks, and |count| is the
- // number of times that particular ID was used.
- std::vector<std::pair<int, int>> ComputePartIDHistogram() const {
- std::vector<int> part_ids(1 << 11, 0);
- std::iota(part_ids.begin(), part_ids.end(), 0);
-
- // The histogram will then pair IDs with counts so that we can sort by
- // the number of instances later on.
- std::vector<std::pair<int, int>> part_id_histogram;
- std::transform(part_ids.begin(), part_ids.end(),
- std::back_inserter(part_id_histogram),
- [](const int& x) { return std::make_pair(x, 0); });
-
- // Actually count the IDs in the list of blocks.
- for (const auto& block : blocks_) {
- if (block.endpoints.size() == 2) {
- const int id = block.partition_id.value();
- assert(part_id_histogram[id].first == id);
- part_id_histogram[id].second++;
- }
- }
-
- struct OrderBySecondGreater {
- typedef std::pair<int, int> PairType;
- bool operator()(const PairType& lhs, const PairType& rhs) {
- return lhs.second > rhs.second;
- }
- };
-
- // Sort by descending numbers of occurrence for each partition ID
- std::sort(part_id_histogram.begin(), part_id_histogram.end(),
- OrderBySecondGreater());
-
- return part_id_histogram;
- }
-
- // Weights range from 2x2 - 12x12. For simplicity define buckets for every
- // pair in [0, 12]^2.
- constexpr static int kResolutionBuckets = 13;
- // Returns a linear array of buckets over all pairs of grid resolutions,
- // x-major in memory.
- std::vector<int> ComputeWeightResolutionHistogram() const {
- // Allocate one bucket for every grid resolution.
- std::vector<int> resolution_histogram(
- kResolutionBuckets * kResolutionBuckets, 0);
-
- // Count the weight resolutions in the list of blocks.
- for (const auto& block : blocks_) {
- const int dim_x = block.weight_grid_dim_x;
- const int dim_y = block.weight_grid_dim_y;
- assert(dim_x > 0);
- assert(dim_x < kResolutionBuckets);
- assert(dim_y > 0);
- assert(dim_y < kResolutionBuckets);
- ++resolution_histogram[dim_x + dim_y * kResolutionBuckets];
- }
-
- return resolution_histogram;
- }
-
- // Runs through each defined statistic and prints it out to stdout. Also
- // prints a histogram of partition ids used for the given blocks.
- void PrintStats() const {
- for (const auto& stat : stats_) {
- stat->PrintToStream(std::cout);
- }
-
- // We also want to find if there are any 2-subset partition IDs that are
- // used disproportionately often. Since partition IDs are 11 bits long, we
- // can have as many as (1 << 11) used IDs in a given sequence of blocks.
- const auto part_id_histogram = ComputePartIDHistogram();
- const int total_part_ids = std::accumulate(
- part_id_histogram.begin(), part_id_histogram.end(), 0,
- [](const int& x, const std::pair<int, int>& hist) {
- return x + hist.second;
- });
-
- if (total_part_ids > 0) {
- // Display numbers until we either:
- // A. Display the top 90% of used partitions
- // B. Reach a point where the remaining partition IDs constitute < 1% of
- // the total number of IDs used.
- const auto prepare_part_entry = []() -> std::ostream& {
- return std::cout << std::setw(6) << std::left << std::setfill('.');
- };
- int part_accum = 0;
- std::cout << "Two subset partition ID histogram: " << std::endl;
- std::cout << " ";
- prepare_part_entry() << "ID" << "Count" << std::endl;
- for (const auto& hist : part_id_histogram) {
- part_accum += hist.second;
- if ((hist.second * 100 / total_part_ids) < 1 ||
- (100 * (total_part_ids - part_accum)) / total_part_ids < 10) {
- const int num_to_display = (total_part_ids - part_accum);
- std::cout << " rest: " << num_to_display
- << " (" << (num_to_display * 100 / total_part_ids)
- << "%)" << std::endl;
- break;
- } else {
- std::cout << " ";
- prepare_part_entry() << hist.first << hist.second
- << " (" << (hist.second * 100 / total_part_ids)
- << "%)" << std::endl;
- }
- }
- }
-
- // Build the 2D histogram of resolutions.
- std::vector<int> weight_histogram = ComputeWeightResolutionHistogram();
- // Labels the weight resolution table.
- std::cout << "Weight resolutions:" << std::endl;
- const auto prepare_weight_entry = []() -> std::ostream& {
- return std::cout << std::setw(6) << std::left << std::setfill(' ');
- };
- prepare_weight_entry() << "H W";
- for (int resolution_x = 2; resolution_x < kResolutionBuckets;
- ++resolution_x) {
- prepare_weight_entry() << resolution_x;
- }
- std::cout << std::endl;
-
- // Displays table; skips rows/cols {0, 1} since they will always be empty.
- for (int resolution_y = 2; resolution_y < kResolutionBuckets;
- ++resolution_y) {
- prepare_weight_entry() << resolution_y;
- for (int resolution_x = 2; resolution_x < kResolutionBuckets;
- ++resolution_x) {
- const int count =
- weight_histogram[resolution_x + resolution_y * kResolutionBuckets];
- prepare_weight_entry();
- if (!count) {
- std::cout << "*";
- } else {
- std::cout << count;
- }
- }
- std::cout << std::endl;
- }
- }
-
- size_t NumBlocks() const { return blocks_.size(); }
-
- private:
- std::vector<std::unique_ptr<Stat>> stats_;
- std::vector<IntermediateBlockData> blocks_;
-};
-
-std::ostream& operator<<(std::ostream& stream, const RgbaColor& color) {
- stream << "{";
- constexpr int kNumChannels = std::tuple_size<RgbaColor>::value;
- for (int i = 0; i < kNumChannels; ++i) {
- stream << color[i];
- if (i < (kNumChannels - 1)) {
- stream << ", ";
- }
- }
- return stream << "}";
-}
-
-void PrintStatsForBlock(const PhysicalASTCBlock& pb,
- astc_codec::Footprint footprint) {
- const auto print_void_extent = [&pb](const VoidExtentData& void_extent_data) {
- std::cout << "Void extent block:" << std::endl;
- std::cout << " 16-bit RGBA: {"
- << void_extent_data.r << ", "
- << void_extent_data.g << ", "
- << void_extent_data.b << ", "
- << void_extent_data.a << "}" << std::endl;
- if (pb.VoidExtentCoords()) {
- std::cout << " Extent (S): {"
- << void_extent_data.coords[0] << ", "
- << void_extent_data.coords[1] << "}" << std::endl;
- std::cout << " Extent (T): {"
- << void_extent_data.coords[2] << ", "
- << void_extent_data.coords[3] << "}" << std::endl;
- } else {
- std::cout << " No valid extent data" << std::endl;
- }
- };
-
- const auto print_endpoint_data =
- [](ColorEndpointMode mode, int endpoint_range,
- const std::vector<int>& encoded_vals) {
- std::cout << " Endpoint mode: "
- << kModeStrings[static_cast<int>(mode)] << std::endl;
- std::cout << " Uses blue-contract mode: "
- << (UsesBlueContract(endpoint_range, mode, encoded_vals)
- ? "true" : "false")
- << std::endl;
-
- RgbaColor endpoint_low, endpoint_high;
- DecodeColorsForMode(encoded_vals, endpoint_range, mode,
- &endpoint_low, &endpoint_high);
-
- std::cout << " Low endpoint: " << endpoint_low << std::endl;
- std::cout << " High endpoint: " << endpoint_high << std::endl;
- };
-
- const auto print_color_data =
- [&print_endpoint_data, &footprint](const IntermediateBlockData& ib_data) {
- const int endpoint_range = ib_data.endpoint_range.value();
- std::cout << "Endpoint range: " << endpoint_range << std::endl;
-
- const int num_parts = ib_data.endpoints.size();
- if (ib_data.partition_id.hasValue()) {
- const int part_id = ib_data.partition_id.value();
- std::cout << "Parititon ID: " << part_id << std::endl;
-
- const auto part = GetASTCPartition(footprint, num_parts, part_id);
- assert(part.assignment.size() == footprint.Height() * footprint.Width());
-
- std::cout << "Assignment:" << std::endl;
- for (int y = 0; y < footprint.Height(); ++y) {
- std::cout << " ";
- for (int x = 0; x < footprint.Width(); ++x) {
- const int texel_index = y * footprint.Width() + x;
- std::cout << " " << part.assignment[texel_index];
- }
- std::cout << std::endl;
- }
- } else {
- std::cout << "Single partition" << std::endl;
- }
-
- int endpoint_index = 0;
- for (const auto& ep_data : ib_data.endpoints) {
- if (num_parts == 1) {
- std::cout << "Endpoints:" << std::endl;
- } else {
- std::cout << "Endpoint " << (endpoint_index++) << ": " << std::endl;
- }
- print_endpoint_data(ep_data.mode, endpoint_range, ep_data.colors);
- }
-
- if (ib_data.dual_plane_channel) {
- std::cout << "Dual plane channel: "
- << ib_data.dual_plane_channel.value() << std::endl;
- } else {
- std::cout << "Single plane" << std::endl;
- }
- };
-
- const auto print_weight_data =
- [&footprint](const IntermediateBlockData& ib_data) {
- std::cout << "Weight grid dimensions: "
- << ib_data.weight_grid_dim_x << "x" << ib_data.weight_grid_dim_y
- << std::endl;
- std::cout << "Weight range: " << ib_data.weight_range << std::endl;
-
- std::cout << "Encoded weight grid: " << std::endl;
- int weight_idx = 0;
- for (int j = 0; j < ib_data.weight_grid_dim_y; ++j) {
- std::cout << " ";
- for (int i = 0; i < ib_data.weight_grid_dim_x; ++i) {
- std::cout << std::setw(3) << std::left << std::setfill(' ')
- << ib_data.weights[weight_idx++];
- }
- std::cout << std::endl;
- }
-
- std::cout << "Actual weight grid: " << std::endl;
- std::vector<int> actual_weights = ib_data.weights;
- for (auto& weight : actual_weights) {
- weight = astc_codec::UnquantizeWeightFromRange(
- weight, ib_data.weight_range);
- }
-
- actual_weights = astc_codec::InfillWeights(
- actual_weights, footprint, ib_data.weight_grid_dim_x,
- ib_data.weight_grid_dim_y);
-
- weight_idx = 0;
- for (int j = 0; j < footprint.Height(); ++j) {
- std::cout << " ";
- for (int i = 0; i < footprint.Width(); ++i) {
- std::cout << std::setw(3) << std::left << std::setfill(' ')
- << actual_weights[weight_idx++];
- }
- std::cout << std::endl;
- }
- };
-
- if (pb.IsVoidExtent()) {
- Optional<VoidExtentData> ve = astc_codec::UnpackVoidExtent(pb);
- if (!ve) {
- std::cerr << "ERROR: Failed to unpack void extent block." << std::endl;
- } else {
- print_void_extent(ve.value());
- }
- } else {
- Optional<IntermediateBlockData> ib =
- astc_codec::UnpackIntermediateBlock(pb);
- if (!ib) {
- std::cerr << "ERROR: Failed to unpack intermediate block." << std::endl;
- } else {
- const auto& ib_data = ib.value();
- print_color_data(ib_data);
- print_weight_data(ib_data);
- }
- }
-}
-
-} // namespace
-
-int main(int argc, char* argv[]) {
- bool error = false;
-
- std::string filename;
- size_t block_index = 0;
- bool has_block_index = false;
-
- if (argc >= 2) {
- filename = argv[1];
-
- if (argc == 3) {
- int32_t param = astc_codec::base::ParseInt32(argv[2], -1);
- if (param < 0) {
- std::cerr << "ERROR: Invalid block index." << std::endl;
- error = true;
- } else {
- block_index = static_cast<size_t>(param);
- has_block_index = true;
- }
- } else if (argc != 2) {
- std::cerr << "ERROR: Too many parameters." << std::endl;
- error = true;
- }
- } else {
- error = true;
- }
-
- if (error) {
- std::cout << ((argc >= 0) ? argv[0] : "astc_inspector_cli")
- << " <filename> [<block index>]" << std::endl
- << std::endl
- << "Collects the various statistics of a stream of ASTC data "
- << "stored in an ASTC file." << std::endl
- << std::endl
- << " filename ASTC file path." << std::endl
- << " block index If specified, show detailed information about a block"
- << std::endl;
- return 1;
- }
-
- std::string error_string;
- std::unique_ptr<ASTCFile> astc_file = ASTCFile::LoadFile(argv[1], &error_string);
- if (!astc_file) {
- std::cerr << "ERROR: " << error_string << std::endl;
- return 2;
- }
-
- if (has_block_index) {
- Optional<astc_codec::Footprint> footprint =
- astc_codec::Footprint::Parse(astc_file->GetFootprintString().c_str());
- if (!footprint) {
- std::cerr << "ERROR: Invalid footprint \"" << astc_file->GetFootprintString() << "\"" << std::endl;
- return 3;
- }
-
- PrintStatsForBlock(astc_file->GetBlock(block_index), footprint.value());
- } else {
- std::cout << "Dimensions: " << astc_file->GetWidth() << "x"
- << astc_file->GetHeight() << ", depth " << astc_file->GetDepth()
- << std::endl;
-
- ASTCFileStats stats(astc_file);
-
- std::cout << std::endl
- << "Total bits used: " << 128 * astc_file->NumBlocks()
- << " (" << astc_file->NumBlocks() << " blocks, "
- << (astc_file->NumBlocks() * 16) << " bytes)"
- << std::endl << std::endl;
-
- stats.PrintStats();
- }
-
- return 0;
-}
diff --git a/third-party/astc-codec/src/decoder/types.h b/third-party/astc-codec/src/decoder/types.h
deleted file mode 100644
index 728d5adf..00000000
--- a/third-party/astc-codec/src/decoder/types.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_ASTC_TYPES_H_
-#define ASTC_CODEC_DECODER_ASTC_TYPES_H_
-
-#include <array>
-#include <string>
-#include <utility>
-
-namespace astc_codec {
-
-// The color endpoint mode determines how the values encoded in the ASTC block
-// are interpreted in order to create the RGBA values for the given endpoint
-// pair. The order of this enum is required to match the ASTC specification in
-// Section C.2.14.
-enum class ColorEndpointMode {
- kLDRLumaDirect = 0,
- kLDRLumaBaseOffset,
- kHDRLumaLargeRange,
- kHDRLumaSmallRange,
- kLDRLumaAlphaDirect,
- kLDRLumaAlphaBaseOffset,
- kLDRRGBBaseScale,
- kHDRRGBBaseScale,
- kLDRRGBDirect,
- kLDRRGBBaseOffset,
- kLDRRGBBaseScaleTwoA,
- kHDRRGBDirect,
- kLDRRGBADirect,
- kLDRRGBABaseOffset,
- kHDRRGBDirectLDRAlpha,
- kHDRRGBDirectHDRAlpha,
-
- // The total number of color endpoints defined by the ASTC specification.
- // This isn't a specific endpoint mode and its sole purpose is to be used
- // as a constant number.
- kNumColorEndpointModes
-};
-
-// Returns the class for the given mode as defined in Section C.2.11.
-constexpr int EndpointModeClass(ColorEndpointMode mode) {
- return static_cast<int>(mode) / 4;
-}
-
-// Returns the number of encoded color values for the given endpoint mode. The
-// number of encoded color values and their range determines the size of the
-// color data in a physical ASTC block. This information is taken from
-// Section C.2.17 of the ASTC specification.
-constexpr int NumColorValuesForEndpointMode(ColorEndpointMode mode) {
- return (EndpointModeClass(mode) + 1) * 2;
-}
-
-// We define a number of convenience types here that give more logical meaning
-// throughout the ASTC utilities.
-using RgbColor = std::array<int, 3>;
-using RgbaColor = std::array<int, 4>;
-using Endpoint = RgbaColor;
-using EndpointPair = std::pair<Endpoint, Endpoint>;
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_ASTC_TYPES_H_
diff --git a/third-party/astc-codec/src/decoder/weight_infill.cc b/third-party/astc-codec/src/decoder/weight_infill.cc
deleted file mode 100644
index 62909aa6..00000000
--- a/third-party/astc-codec/src/decoder/weight_infill.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/decoder/weight_infill.h"
-#include "src/decoder/integer_sequence_codec.h"
-
-#include <array>
-#include <cmath>
-#include <utility>
-
-namespace astc_codec {
-
-namespace {
-
-// The following functions are based on Section C.2.18 of the ASTC specification
-int GetScaleFactorD(int block_dim) {
- return static_cast<int>((1024.f + static_cast<float>(block_dim >> 1)) /
- static_cast<float>(block_dim - 1));
-}
-
-std::pair<int, int> GetGridSpaceCoordinates(
- Footprint footprint, int s, int t, int weight_dim_x, int weight_dim_y) {
- const int ds = GetScaleFactorD(footprint.Width());
- const int dt = GetScaleFactorD(footprint.Height());
-
- const int cs = ds * s;
- const int ct = dt * t;
-
- const int gs = (cs * (weight_dim_x - 1) + 32) >> 6;
- const int gt = (ct * (weight_dim_y - 1) + 32) >> 6;
-
- assert(gt < 1 << 8);
- assert(gs < 1 << 8);
-
- return std::make_pair(gs, gt);
-}
-
-// Returns the weight-grid values that are to be used for bilinearly
-// interpolating the weight to its final value. If the returned value
-// is equal to weight_dim_x * weight_dim_y, it may be ignored.
-std::array<int, 4> BilerpGridPointsForWeight(
- const std::pair<int, int>& grid_space_coords, int weight_dim_x) {
- const int js = grid_space_coords.first >> 4;
- const int jt = grid_space_coords.second >> 4;
-
- std::array<int, 4> result;
- result[0] = js + weight_dim_x * jt;
- result[1] = js + weight_dim_x * jt + 1;
- result[2] = js + weight_dim_x * (jt + 1);
- result[3] = js + weight_dim_x * (jt + 1) + 1;
-
- return result;
-}
-
-std::array<int, 4> BilerpGridPointFactorsForWeight(
- const std::pair<int, int>& grid_space_coords) {
- const int fs = grid_space_coords.first & 0xF;
- const int ft = grid_space_coords.second & 0xF;
-
- std::array<int, 4> result;
- result[3] = (fs * ft + 8) >> 4;
- result[2] = ft - result[3];
- result[1] = fs - result[3];
- result[0] = 16 - fs - ft + result[3];
-
- assert(result[0] <= 16);
- assert(result[1] <= 16);
- assert(result[2] <= 16);
- assert(result[3] <= 16);
-
- return result;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-int CountBitsForWeights(int weight_dim_x, int weight_dim_y,
- int target_weight_range) {
- int num_weights = weight_dim_x * weight_dim_y;
- return IntegerSequenceCodec::
- GetBitCountForRange(num_weights, target_weight_range);
-}
-
-std::vector<int> InfillWeights(const std::vector<int>& weights,
- Footprint footprint, int dim_x, int dim_y) {
- std::vector<int> result;
- result.reserve(footprint.NumPixels());
- for (int t = 0; t < footprint.Height(); ++t) {
- for (int s = 0; s < footprint.Width(); ++s) {
- const auto grid_space_coords =
- GetGridSpaceCoordinates(footprint, s, t, dim_x, dim_y);
- const auto grid_pts =
- BilerpGridPointsForWeight(grid_space_coords, dim_x);
- const auto grid_factors =
- BilerpGridPointFactorsForWeight(grid_space_coords);
-
- int weight = 0;
- for (int i = 0; i < 4; ++i) {
- if (grid_pts[i] < dim_x * dim_y) {
- weight += weights.at(grid_pts[i]) * grid_factors[i];
- }
- }
- result.push_back((weight + 8) >> 4);
- }
- }
-
- return result;
-}
-
-} // namespace astc_codec
diff --git a/third-party/astc-codec/src/decoder/weight_infill.h b/third-party/astc-codec/src/decoder/weight_infill.h
deleted file mode 100644
index 4a09d358..00000000
--- a/third-party/astc-codec/src/decoder/weight_infill.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ASTC_CODEC_DECODER_WEIGHT_INFILL_H_
-#define ASTC_CODEC_DECODER_WEIGHT_INFILL_H_
-
-#include "src/decoder/footprint.h"
-
-#include <vector>
-
-namespace astc_codec {
-
-// Returns the number of bits used to represent the weight grid at the target
-// dimensions and weight range.
-int CountBitsForWeights(int weight_dim_x, int weight_dim_y,
- int target_weight_range);
-
-// Performs weight infill of a grid of weights of size |dim_x * dim_y|. The
-// weights are fit using the algorithm laid out in Section C.2.18 of the ASTC
-// specification. Weights are expected to be passed unquantized and the returned
-// grid will be unquantized as well (i.e. each weight within the range [0, 64]).
-std::vector<int> InfillWeights(const std::vector<int>& weights,
- Footprint footprint, int dim_x, int dim_y);
-
-} // namespace astc_codec
-
-#endif // ASTC_CODEC_DECODER_WEIGHT_INFILL_H_
diff --git a/third-party/astc-codec/third_party/honggfuzz.BUILD b/third-party/astc-codec/third_party/honggfuzz.BUILD
deleted file mode 100644
index 67a44bee..00000000
--- a/third-party/astc-codec/third_party/honggfuzz.BUILD
+++ /dev/null
@@ -1,34 +0,0 @@
-config_setting(
- name = "opt",
- values = {"compilation_mode": "opt"}
-)
-
-cc_library(
- name = "honggfuzz",
- srcs = glob([
- "libhfuzz/*.c",
- "libhfcommon/*.c",
- ],
- exclude = ["libhfuzz/linux.c"],
- ) + select({
- "@bazel_tools//src/conditions:darwin_x86_64": [],
- "@bazel_tools//src/conditions:darwin": [],
- "//conditions:default": ["libhfuzz/linux.c"],
- }),
- hdrs = glob([
- "libhfuzz/*.h",
- "libhfcommon/*.h",
- "honggfuzz.h",
- ]),
- defines = select({
- "@bazel_tools//src/conditions:darwin_x86_64": ["_HF_ARCH_DARWIN"],
- "@bazel_tools//src/conditions:darwin": ["_HF_ARCH_DARWIN"],
- "//conditions:default": ["_HF_ARCH_LINUX", "linux=linux"],
- }) + select({
- ":opt": [],
- "//conditions:default": ["DEBUG=DEBUG"],
- }),
- includes = ["."],
- visibility = ["//visibility:public"],
- linkstatic = 1
-)
diff --git a/third-party/astc-codec/tools/bazel.rc b/third-party/astc-codec/tools/bazel.rc
deleted file mode 100644
index e47b0069..00000000
--- a/third-party/astc-codec/tools/bazel.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-# For building with the clang-specific flavor of ASAN.
-build:clang-asan --client_env=CC=clang-5.0
-build:clang-asan --copt -g3
-build:clang-asan --copt -fsanitize=address
-build:clang-asan --linkopt -fsanitize=address
-build:clang-asan --copt -fno-omit-frame-pointer