31#include <initializer_list>
37#include <gtest/gtest.h>
44struct BaselineCodeTag;
48using rawspeed::BaselineCodeTag;
65 auto str = std::bitset<32>(
s.code).to_string();
67 str = str.substr(str.size() -
s.code_len);
68 return os <<
"0b" << str;
82TEST(HuffmanCodeCodeSymbolTest, Equality) {
83#define s HuffmanCode<BaselineCodeTag>::CodeSymbol
84 ASSERT_EQ(
s(0, 1),
s(0, 1));
85 ASSERT_EQ(
s(1, 1),
s(1, 1));
87 ASSERT_NE(
s(1, 1),
s(0, 1));
88 ASSERT_NE(
s(0, 1),
s(1, 1));
100 "code_len <= Traits::MaxCodeLenghtBits");
103 "code_len <= Traits::MaxCodeLenghtBits");
113 val = std::get<0>(p);
114 len = std::get<1>(p);
115 die = std::get<2>(p);
124 make_tuple(0b00, 1,
false),
125 make_tuple(0b00, 2,
false),
126 make_tuple(0b01, 1,
false),
127 make_tuple(0b01, 2,
false),
128 make_tuple(0b10, 1,
true),
129 make_tuple(0b10, 2,
false),
130 make_tuple(0b11, 1,
true),
131 make_tuple(0b11, 2,
false),
145 "code <= \\(\\(1U << code_len\\) - 1U\\)");
155 ::testing::ExitedWithCode(0),
"");
162 :
public ::testing::TestWithParam<CodeSymbolPrintDataType> {
168 val = std::get<0>(p);
169 len = std::get<1>(p);
170 str = std::get<2>(p);
179 make_tuple(0b00, 1,
"0b0"),
180 make_tuple(0b00, 2,
"0b00"),
181 make_tuple(0b01, 1,
"0b1"),
182 make_tuple(0b01, 2,
"0b01"),
183 make_tuple(0b10, 2,
"0b10"),
184 make_tuple(0b11, 2,
"0b11"),
199 std::tuple<HuffmanCode<BaselineCodeTag>::CodeSymbol,
202 :
public ::testing::TestWithParam<CodeSymbolHaveCommonPrefixDataType> {
215std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>
218 static constexpr auto maxLen = 2U;
219 static constexpr auto expectedCnt = 2U + 4U;
221 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol> allVariants;
222 allVariants.reserve(expectedCnt);
223 for (
unsigned l = 1; l <= maxLen; l++) {
224 for (
unsigned c = 0; c <= ((1U << l) - 1U); c++)
225 allVariants.emplace_back(c, l);
227 assert(allVariants.size() == expectedCnt);
236 if (partial.code_len > symbol.code_len)
239 auto symbol_str = ::testing::PrintToString(symbol);
240 auto partial_str = ::testing::PrintToString(partial);
241 const auto len = std::min(symbol_str.length(), partial_str.length());
243 symbol_str.resize(len);
244 partial_str.resize(len);
247 symbol_str == partial_str)
248 <<
"Where symbol_str = " << symbol_str
249 <<
", partial_str = " << partial_str;
259 {0b0, 1}, {0b0, 1}));
261 {0b10, 2}, {0b1, 1}));
263 {0b10, 2}, {0b0, 1}));
265 {0b10, 2}, {0b01, 2}));
269TEST(CodeSymbolHaveCommonPrefixDeathTest, AsymmetricalDeathTest) {
275 "partial.code_len <= symbol.code_len");
281 "partial.code_len <= symbol.code_len");
285auto genHT = [](std::initializer_list<uint8_t>&& nCodesPerLength)
288 std::vector<uint8_t> v(nCodesPerLength.begin(), nCodesPerLength.end());
298 [](std::initializer_list<uint8_t>&& nCodesPerLength) ->
uint32_t {
300 std::vector<uint8_t> v(nCodesPerLength.begin(), nCodesPerLength.end());
307auto genHTFull = [](std::initializer_list<uint8_t>&& nCodesPerLength,
308 std::initializer_list<uint8_t>&& codeValues)
310 auto hc =
genHT(std::move(nCodesPerLength));
311 std::vector<uint8_t> v(codeValues.begin(), codeValues.end());
319TEST(HuffmanCodeDeathTest, setNCodesPerLengthRequires16Lengths) {
320 for (
int i = 1; i < 32; i++) {
321 std::vector<uint8_t> v(i, 1);
322 ASSERT_EQ(v.size(), i);
334 "data.getSize\\(\\) == Traits::MaxCodeLenghtBits");
342 ::testing::ExitedWithCode(0),
"");
348TEST(HuffmanCodeTest, setNCodesPerLengthEqualCompareAndTrimming) {
370TEST(HuffmanCodeTest, setNCodesPerLengthEmptyIsBad) {
376TEST(HuffmanCodeTest, setNCodesPerLengthTooManyCodesTotal) {
377 ASSERT_NO_THROW(
genHT({0, 0, 0, 0, 0, 0, 0, 162}));
378 ASSERT_THROW(
genHT({0, 0, 0, 0, 0, 0, 0, 163}),
382TEST(HuffmanCodeTest, setNCodesPerLengthTooManyCodesForLength) {
383 for (
int len = 1; len < 8; len++) {
385 std::vector<uint8_t> v(16, 0);
388 for (
auto i = 1U; i <= (1U << len); i++) {
397TEST(HuffmanCodeTest, setNCodesPerLengthCodeSymbolOverflow) {
398 ASSERT_NO_THROW(
genHT({1}));
399 ASSERT_NO_THROW(
genHT({2}));
401 ASSERT_NO_THROW(
genHT({1, 2}));
404 ASSERT_NO_THROW(
genHT({0, 4}));
408TEST(HuffmanCodeTest, setNCodesPerLengthCounts) {
419TEST(HuffmanCodeDeathTest, setCodeValuesRequiresCount) {
420 for (
int len = 1; len < 8; len++) {
422 std::vector<uint8_t> l(16, 0);
427 std::vector<uint8_t> v;
428 v.reserve(count + 1);
429 for (
auto cnt = count - 1; cnt <= count + 1; cnt++) {
436 { ht.
setCodeValues(bv); },
"static_cast<unsigned>\\(data.size\\(\\)"
437 "\\) == maxCodesCount\\(\\)");
444 ::testing::ExitedWithCode(0),
"");
450TEST(HuffmanCodeDeathTest, setCodeValuesRequiresLessThan162) {
451 auto ht =
genHT({0, 0, 0, 0, 0, 0, 0, 162});
452 std::vector<uint8_t> v(163, 0);
456 { ht.setCodeValues(bv); },
"data.size\\(\\) <= Traits::MaxNumCodeValues");
460TEST(HuffmanCodeTest, setCodeValuesValueLessThan16) {
461 auto ht =
genHT({1});
462 std::vector<uint8_t> v(1);
464 for (
int i = 0; i < 256; i++) {
469 ASSERT_NO_THROW(ht.setCodeValues(b););
473TEST(HuffmanCodeTest, EqualCompareAndTrimming) {
496 diff = std::get<0>(p);
497 len = std::get<1>(p);
498 value = std::get<2>(p);
506auto zeroDiff = [](
int len) {
return make_tuple(0, len, -((1 << len) - 1)); };
508 return make_tuple(((1 << len) - 1), len, ((1 << len) - 1));
510auto one = [](
int len) {
return make_tuple((1 << len), len, 1); };
564 make_tuple(0b00, 0b01, -0b001),
565 make_tuple(0b01, 0b01, 0b001),
566 make_tuple(0b10, 0b01, 0b001),
567 make_tuple(0b11, 0b01, 0b011),
568 make_tuple(0b00, 0b10, -0b011),
569 make_tuple(0b01, 0b10, -0b010),
570 make_tuple(0b10, 0b10, 0b010),
571 make_tuple(0b11, 0b10, 0b011),
572 make_tuple(0b00, 0b11, -0b111),
573 make_tuple(0b01, 0b11, -0b110),
574 make_tuple(0b10, 0b11, -0b101),
575 make_tuple(0b11, 0b11, -0b100),
587 std::tuple<std::vector<uint8_t>,
588 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>>;
590 :
public ::testing::TestWithParam<generateCodeSymbolsDataType> {
596 ncpl = std::get<0>(p);
605 make_tuple(std::vector<uint8_t>{1},
606 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>{{0b0, 1}}),
608 make_tuple(std::vector<uint8_t>{0, 1},
609 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>{
612 make_tuple(std::vector<uint8_t>{0, 2},
613 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>{
617 make_tuple(std::vector<uint8_t>{0, 3},
618 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>{
624 make_tuple(std::vector<uint8_t>{1, 1},
625 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>{
629 make_tuple(std::vector<uint8_t>{1, 2},
630 std::vector<HuffmanCode<BaselineCodeTag>::CodeSymbol>{
644 std::vector<uint8_t> cv(cnt, 0);
INSTANTIATE_TEST_SUITE_P(MD5Test, MD5Test, ::testing::ValuesIn(testCases))
TEST_P(MD5Test, CheckTestCaseSet)
assert(dim.area() >=area)
static int RAWSPEED_READNONE extend(uint32_t diff, uint32_t len)
size_type RAWSPEED_READONLY getSize() const
uint32_t setNCodesPerLength(Buffer data)
std::vector< CodeSymbol > generateCodeSymbols() const
typename AbstractPrefixCode< CodeTag >::CodeSymbol CodeSymbol
void setCodeValues(Array1DRef< const typename Traits::CodeValueTy > data)
CodeSymbolDeathTest()=default
HuffmanCode< BaselineCodeTag >::CodeSymbol symbol
HuffmanCode< BaselineCodeTag >::CodeSymbol partial
CodeSymbolHaveCommonPrefixTest()=default
CodeSymbolPrintTest()=default
std::vector< uint8_t > ncpl
std::vector< HuffmanCode< BaselineCodeTag >::CodeSymbol > expectedSymbols
generateCodeSymbolsTest()=default
std::tuple< std::vector< uint8_t >, std::vector< HuffmanCode< BaselineCodeTag >::CodeSymbol > > generateCodeSymbolsDataType
const CodeSymbolPrintDataType CodeSymbolPrintData[]
std::vector< HuffmanCode< BaselineCodeTag >::CodeSymbol > GenerateAllPossibleCodeSymbols()
std::tuple< int, int, std::string > CodeSymbolPrintDataType
const SignExtendDataType signExtendData[]
const generateCodeSymbolsDataType generateCodeSymbolsData[]
const CodeSymbolType CodeSymbolData[]
const auto allPossibleCodeSymbols
std::tuple< HuffmanCode< BaselineCodeTag >::CodeSymbol, HuffmanCode< BaselineCodeTag >::CodeSymbol > CodeSymbolHaveCommonPrefixDataType
TEST(HuffmanCodeCodeSymbolTest, Equality)
std::tuple< int, int, bool > CodeSymbolType
std::tuple< uint32_t, uint32_t, int > SignExtendDataType
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
bool operator!=(const AlignedAllocator< T1, A1 > &, const AlignedAllocator< T2, A2 > &)
static inline ::std::ostream & operator<<(::std::ostream &os, const T &b)