blob: d5dfad946b7c62ef0a343ae4811fc9bce3fa4313 [file] [log] [blame]
/*
* Copyright (c) 2018, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include "aom/aom_integer.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
namespace {
const uint64_t kMaximumLeb128CodedSize = 8;
const uint8_t kLeb128PadByte = 0x80; // Binary: 10000000
const uint64_t kMaximumLeb128Value = UINT32_MAX;
const uint32_t kSizeTestNumValues = 6;
const uint32_t kSizeTestExpectedSizes[kSizeTestNumValues] = {
1, 1, 2, 3, 4, 5
};
const uint64_t kSizeTestInputs[kSizeTestNumValues] = { 0, 0x7f,
0x3fff, 0x1fffff,
0xffffff, 0x10000000 };
const uint8_t kOutOfRangeLeb128Value[5] = { 0x80, 0x80, 0x80, 0x80,
0x10 }; // UINT32_MAX + 1
} // namespace
TEST(AomLeb128, DecodeTest) {
const size_t num_leb128_bytes = 3;
const uint8_t leb128_bytes[num_leb128_bytes] = { 0xE5, 0x8E, 0x26 };
const uint64_t expected_value = 0x98765; // 624485
const size_t expected_length = 3;
uint64_t value = ~0ULL; // make sure value is cleared by the function
size_t length;
ASSERT_EQ(
aom_uleb_decode(&leb128_bytes[0], num_leb128_bytes, &value, &length), 0);
ASSERT_EQ(expected_value, value);
ASSERT_EQ(expected_length, length);
// Make sure the decoder stops on the last marked LEB128 byte.
aom_uleb_decode(&leb128_bytes[0], num_leb128_bytes + 1, &value, &length);
ASSERT_EQ(expected_value, value);
ASSERT_EQ(expected_length, length);
}
TEST(AomLeb128, EncodeTest) {
const uint32_t test_value = 0x98765; // 624485
const uint8_t expected_bytes[3] = { 0xE5, 0x8E, 0x26 };
const size_t kWriteBufferSize = 4;
uint8_t write_buffer[kWriteBufferSize] = { 0 };
size_t bytes_written = 0;
ASSERT_EQ(aom_uleb_encode(test_value, kWriteBufferSize, &write_buffer[0],
&bytes_written),
0);
ASSERT_EQ(bytes_written, 3u);
for (size_t i = 0; i < bytes_written; ++i) {
ASSERT_EQ(write_buffer[i], expected_bytes[i]);
}
}
TEST(AomLeb128, EncodeDecodeTest) {
const uint32_t value = 0x98765; // 624485
const size_t kWriteBufferSize = 4;
uint8_t write_buffer[kWriteBufferSize] = { 0 };
size_t bytes_written = 0;
ASSERT_EQ(aom_uleb_encode(value, kWriteBufferSize, &write_buffer[0],
&bytes_written),
0);
ASSERT_EQ(bytes_written, 3u);
uint64_t decoded_value;
size_t decoded_length;
aom_uleb_decode(&write_buffer[0], bytes_written, &decoded_value,
&decoded_length);
ASSERT_EQ(value, decoded_value);
ASSERT_EQ(bytes_written, decoded_length);
}
TEST(AomLeb128, FixedSizeEncodeTest) {
const uint32_t test_value = 0x123;
const uint8_t expected_bytes[4] = { 0xa3, 0x82, 0x80, 0x00 };
const size_t kWriteBufferSize = 4;
uint8_t write_buffer[kWriteBufferSize] = { 0 };
size_t bytes_written = 0;
ASSERT_EQ(0, aom_uleb_encode_fixed_size(test_value, kWriteBufferSize,
kWriteBufferSize, &write_buffer[0],
&bytes_written));
ASSERT_EQ(kWriteBufferSize, bytes_written);
for (size_t i = 0; i < bytes_written; ++i) {
ASSERT_EQ(write_buffer[i], expected_bytes[i]);
}
}
TEST(AomLeb128, FixedSizeEncodeDecodeTest) {
const uint32_t value = 0x1;
const size_t kWriteBufferSize = 4;
uint8_t write_buffer[kWriteBufferSize] = { 0 };
size_t bytes_written = 0;
ASSERT_EQ(
aom_uleb_encode_fixed_size(value, kWriteBufferSize, kWriteBufferSize,
&write_buffer[0], &bytes_written),
0);
ASSERT_EQ(bytes_written, 4u);
uint64_t decoded_value;
size_t decoded_length;
aom_uleb_decode(&write_buffer[0], bytes_written, &decoded_value,
&decoded_length);
ASSERT_EQ(value, decoded_value);
ASSERT_EQ(bytes_written, decoded_length);
}
TEST(AomLeb128, SizeTest) {
for (size_t i = 0; i < kSizeTestNumValues; ++i) {
ASSERT_EQ(kSizeTestExpectedSizes[i],
aom_uleb_size_in_bytes(kSizeTestInputs[i]));
}
}
TEST(AomLeb128, DecodeFailTest) {
// Input buffer containing what would be a valid 9 byte LEB128 encoded
// unsigned integer.
const uint8_t kAllPadBytesBuffer[kMaximumLeb128CodedSize + 1] = {
kLeb128PadByte, kLeb128PadByte, kLeb128PadByte,
kLeb128PadByte, kLeb128PadByte, kLeb128PadByte,
kLeb128PadByte, kLeb128PadByte, 0
};
uint64_t decoded_value;
// Test that decode fails when result would be valid 9 byte integer.
ASSERT_EQ(aom_uleb_decode(&kAllPadBytesBuffer[0], kMaximumLeb128CodedSize + 1,
&decoded_value, NULL),
-1);
// Test that encoded value missing terminator byte within available buffer
// range causes decode error.
ASSERT_EQ(aom_uleb_decode(&kAllPadBytesBuffer[0], kMaximumLeb128CodedSize,
&decoded_value, NULL),
-1);
// Test that LEB128 input that decodes to a value larger than 32-bits fails.
size_t value_size = 0;
ASSERT_EQ(aom_uleb_decode(&kOutOfRangeLeb128Value[0],
sizeof(kOutOfRangeLeb128Value), &decoded_value,
&value_size),
-1);
}
TEST(AomLeb128, EncodeFailTest) {
const size_t kWriteBufferSize = 4;
const uint32_t kValidTestValue = 1;
uint8_t write_buffer[kWriteBufferSize] = { 0 };
size_t coded_size = 0;
ASSERT_EQ(
aom_uleb_encode(kValidTestValue, kWriteBufferSize, NULL, &coded_size),
-1);
ASSERT_EQ(aom_uleb_encode(kValidTestValue, kWriteBufferSize, &write_buffer[0],
NULL),
-1);
const uint32_t kValueOutOfRangeForBuffer = 0xFFFFFFFF;
ASSERT_EQ(aom_uleb_encode(kValueOutOfRangeForBuffer, kWriteBufferSize,
&write_buffer[0], &coded_size),
-1);
const uint64_t kValueOutOfRange = kMaximumLeb128Value + 1;
ASSERT_EQ(aom_uleb_encode(kValueOutOfRange, kWriteBufferSize,
&write_buffer[0], &coded_size),
-1);
const size_t kPadSizeOutOfRange = 5;
ASSERT_EQ(aom_uleb_encode_fixed_size(kValidTestValue, kWriteBufferSize,
kPadSizeOutOfRange, &write_buffer[0],
&coded_size),
-1);
}