Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit b56a500

Browse files
author
Jeff McGlynn
committed
Initial version of astc-codec for open source release
Contains an implementation of an ASTC decoder that is able to pass the dEQP ASTC LDR tests. astc-codec has no external dependencies for the main library, only for test code, and is licensed under the Apache license. Components: include/ - Public API that can decode ASTC LDR data into a RGBA UNORM8 buffer. src/base/ - Base library with common functionality not directly related to ASTC decoding. Contains a uint128 implementation, BitStream for reading/writing bits with a primitive (or uint128 type), Optional implementation (to not take a dependency on C++17), and more. src/decoder/ - Internal implementation of the ASTC decoder. src/base/test/, src/decoder/test/ - Unit tests (and a fuzzing test) for the astc decoder. src/decoder/testdata/ - Sample ASTC images and golden image results for testing. src/decoder/tools/ - A tool to inspect contents of an ASTC file. third_party/ - Third party libraries, only used for tests. Change-Id: Ia98e5a7dc847daa3d3a48c5e62d94b8fb1cb98bd
1 parent ce724a5 commit b56a500

112 files changed

Lines changed: 12548 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,16 @@
1313
# limitations under the License.
1414

1515
licenses(["notice"])
16+
17+
cc_library(
18+
name = "api",
19+
hdrs = ["include/astc-codec/astc-codec.h"],
20+
visibility = ["//src/decoder:__pkg__"],
21+
)
22+
23+
cc_library(
24+
name = "astc_codec",
25+
deps = ["//src/decoder:codec"],
26+
includes = ["include"],
27+
visibility = ["//visibility:public"],
28+
)

README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,41 @@
33
astc-codec is a software ASTC decoder implementation, which supports the ASTC
44
LDR profile.
55

6+
Example usage:
7+
8+
```
9+
#include <astc-codec/astc-codec.h>
10+
11+
// ...
12+
13+
std::vector<uint8_t> astc = LoadMyASTCData();
14+
const size_t width = 640;
15+
const size_t height = 480;
16+
17+
std::vector<uint8_t> result;
18+
result.resize(width * height * 4);
19+
20+
bool result = astc_codec::ASTCDecompressToRGBA(
21+
astc.data(), astc.size(), width, height, astc_codec::FootprintType::k4x4,
22+
result.data(), result.size(), /* stride */ width * 4);
23+
```
24+
25+
## Building
26+
27+
Install [Bazel](https://bazel.build/), and then run:
28+
29+
```
30+
bazel build :astc_codec -c opt
31+
```
32+
33+
astc-codec has been tested on Mac and Linux.
34+
35+
## Run Tests
36+
37+
```
38+
bazel test //...
39+
```
40+
641
## Contributing
742

843
See [CONTRIBUTING.md](CONTRIBUTING.md) for important contributing requirements.
@@ -12,4 +47,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for important contributing requirements.
1247
astc-codec project is licensed under the Apache License Version 2.0. You can
1348
find a copy of it in [LICENSE](LICENSE).
1449

15-
This is not an official Google product.
50+
This is not an officially supported Google product.

include/astc-codec/astc-codec.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef ASTC_CODEC_ASTC_CODEC_H_
16+
#define ASTC_CODEC_ASTC_CODEC_H_
17+
18+
#include <cstddef>
19+
#include <cstdint>
20+
21+
namespace astc_codec {
22+
23+
// These are the valid ASTC footprints according to the specification in
24+
// Section C.2.7.
25+
enum class FootprintType {
26+
k4x4,
27+
k5x4,
28+
k5x5,
29+
k6x5,
30+
k6x6,
31+
k8x5,
32+
k8x6,
33+
k10x5,
34+
k10x6,
35+
k8x8,
36+
k10x8,
37+
k10x10,
38+
k12x10,
39+
k12x12,
40+
41+
kCount
42+
};
43+
44+
// Decompresses ASTC LDR image data to a RGBA32 buffer.
45+
//
46+
// Supports formats defined in the KHR_texture_compression_astc_ldr spec and
47+
// returns UNORM8 values. sRGB is not supported, and should be implemented
48+
// by the caller.
49+
//
50+
// |astc_data| - Compressed ASTC image buffer, must be at least |astc_data_size|
51+
// bytes long.
52+
// |astc_data_size| - The size of |astc_data|, in bytes.
53+
// |width| - Image width, in pixels.
54+
// |height| - Image height, in pixels.
55+
// |footprint| - The ASTC footprint (block size) of the compressed image buffer.
56+
// |out_buffer| - Pointer to a buffer where the decompressed image will be
57+
// stored, must be at least |out_buffer_size| bytes long.
58+
// |out_buffer_size| - The size of |out_buffer|, in bytes, at least
59+
// height*out_buffer_stride. If this is too small, this
60+
// function will return false and no data will be
61+
// decompressed.
62+
// |out_buffer_stride| - The stride that should be used to store rows of the
63+
// decoded image, must be at least 4*width bytes.
64+
//
65+
// Returns true if the decompression succeeded, or false if decompression
66+
// failed, or if the astc_data_size was too small for the given width, height,
67+
// and footprint, or if out_buffer_size is too small.
68+
bool ASTCDecompressToRGBA(const uint8_t* astc_data, size_t astc_data_size,
69+
size_t width, size_t height, FootprintType footprint,
70+
uint8_t* out_buffer, size_t out_buffer_size,
71+
size_t out_buffer_stride);
72+
73+
} // namespace astc_codec
74+
75+
#endif // ASTC_CODEC_ASTC_CODEC_H_

src/.clang-format

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
BasedOnStyle: Google
2+
AllowShortCaseLabelsOnASingleLine: true
3+
AllowShortFunctionsOnASingleLine: Inline
4+
SpaceAfterTemplateKeyword: false

src/base/BUILD.bazel

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
cc_library(
16+
name = "base",
17+
hdrs = [
18+
"bit_stream.h",
19+
"bottom_n.h",
20+
"math_utils.h",
21+
"optional.h",
22+
"string_utils.h",
23+
"type_traits.h",
24+
"uint128.h",
25+
],
26+
visibility = ["//src/decoder:__pkg__"],
27+
)
28+
29+
cc_test(
30+
name = "base_test",
31+
srcs = [
32+
"test/bit_stream_test.cpp",
33+
"test/bottom_n_test.cpp",
34+
"test/math_utils_test.cpp",
35+
"test/optional_test.cpp",
36+
"test/string_utils_test.cpp",
37+
"test/type_traits_test.cpp",
38+
"test/uint128_test.cpp",
39+
],
40+
deps = [
41+
"@gtest//:gtest_main",
42+
":base",
43+
],
44+
)
45+

src/base/bit_stream.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef ASTC_CODEC_BASE_BIT_STREAM_H_
16+
#define ASTC_CODEC_BASE_BIT_STREAM_H_
17+
18+
#include <cassert>
19+
#include <cstdint>
20+
21+
namespace astc_codec {
22+
namespace base {
23+
24+
// Represents a stream of bits that can be read or written in arbitrary-sized
25+
// chunks.
26+
template<typename IntType = uint64_t>
27+
class BitStream {
28+
public:
29+
// Creates an empty BitStream.
30+
BitStream() = default;
31+
BitStream(IntType data, uint32_t data_size)
32+
: data_(data), data_size_(data_size) {
33+
assert(data_size_ <= sizeof(data_) * 8);
34+
}
35+
36+
// Return the number of bits in the stream.
37+
uint32_t Bits() const { return data_size_; }
38+
39+
// Put |size| bits into the stream.
40+
// Fails if there is not enough space in the buffer to store the bits.
41+
template<typename ResultType>
42+
void PutBits(ResultType x, uint32_t size) {
43+
assert(data_size_ + size <= sizeof(data_) * 8);
44+
45+
data_ |= (IntType(x) & MaskFor(size)) << data_size_;
46+
data_size_ += size;
47+
}
48+
49+
// Get |count| bits from the stream.
50+
// Returns true if |count| bits were successfully retrieved.
51+
template<typename ResultType>
52+
bool GetBits(uint32_t count, ResultType* result) {
53+
if (count <= data_size_) {
54+
*result = static_cast<ResultType>(data_ & MaskFor(count));
55+
data_ = data_ >> count;
56+
data_size_ -= count;
57+
return true;
58+
} else {
59+
*result = 0;
60+
return false;
61+
}
62+
}
63+
64+
private:
65+
IntType MaskFor(uint32_t bits) const {
66+
return (bits == sizeof(IntType) * 8) ? ~IntType(0)
67+
: (IntType(1) << bits) - 1;
68+
}
69+
70+
IntType data_ = 0;
71+
uint32_t data_size_ = 0;
72+
};
73+
74+
} // namespace base
75+
} // namespace astc_codec
76+
77+
#endif // ASTC_CODEC_BASE_BIT_STREAM_H_

src/base/bottom_n.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef ASTC_CODEC_BASE_BOTTOM_N_H_
16+
#define ASTC_CODEC_BASE_BOTTOM_N_H_
17+
18+
#include <algorithm>
19+
#include <functional>
20+
#include <vector>
21+
22+
namespace astc_codec {
23+
namespace base {
24+
25+
// Used to aggregate the lowest N values of data supplied.
26+
template<typename T, typename CompareFn = std::less<T>>
27+
class BottomN {
28+
public:
29+
typedef std::vector<T> ContainerType;
30+
31+
// Creates an empty BottomN with limit |max_size|.
32+
BottomN(size_t max_size) : max_size_(max_size) { }
33+
34+
bool Empty() const { return data_.empty(); }
35+
size_t Size() const { return data_.size(); }
36+
37+
const T& Top() const { return data_.front(); }
38+
39+
void Push(const T& value) {
40+
if (data_.size() < max_size_ || compare_(value, Top())) {
41+
data_.push_back(value);
42+
std::push_heap(data_.begin(), data_.end(), compare_);
43+
44+
if (Size() > max_size_) {
45+
PopTop();
46+
}
47+
}
48+
}
49+
50+
std::vector<T> Pop() {
51+
const size_t len = Size();
52+
std::vector<T> result(len);
53+
54+
for (size_t i = 0; i < len; ++i) {
55+
result[len - i - 1] = PopTop();
56+
}
57+
58+
return result;
59+
}
60+
61+
private:
62+
T PopTop() {
63+
std::pop_heap(data_.begin(), data_.end(), compare_);
64+
T result = data_.back();
65+
data_.pop_back();
66+
return result;
67+
}
68+
69+
ContainerType data_;
70+
CompareFn compare_;
71+
72+
const size_t max_size_;
73+
};
74+
75+
} // namespace base
76+
} // namespace astc_codec
77+
78+
#endif // ASTC_CODEC_BASE_BOTTOM_N_H_

0 commit comments

Comments
 (0)