diff options
author | David Bremner <bremner@debian.org> | 2018-12-25 22:44:44 +0900 |
---|---|---|
committer | David Bremner <bremner@debian.org> | 2018-12-25 22:44:44 +0900 |
commit | 33cc53ba511843ac9857470e74e043013d3620fe (patch) | |
tree | ebc0e94b5486710fc2f381d92fab9a594f1dc62c /src/external/rawspeed/test | |
parent | 1fddb41abdd4ca3be5bfdfe019e126b188879e15 (diff) |
Importing darktable_2.6.0.orig.tar.xz
Diffstat (limited to 'src/external/rawspeed/test')
27 files changed, 1868 insertions, 114 deletions
diff --git a/src/external/rawspeed/test/librawspeed/CMakeLists.txt b/src/external/rawspeed/test/librawspeed/CMakeLists.txt index e51f669a0..f3f9a396f 100644 --- a/src/external/rawspeed/test/librawspeed/CMakeLists.txt +++ b/src/external/rawspeed/test/librawspeed/CMakeLists.txt @@ -9,10 +9,6 @@ target_link_libraries(rawspeed_test PUBLIC rawspeed) target_link_libraries(rawspeed_test PUBLIC gtest gmock_main) target_include_directories(rawspeed_test PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") -if(WITH_OPENMP AND OPENMP_FOUND AND TARGET OpenMP::OpenMP) - target_link_libraries(rawspeed_test PUBLIC OpenMP::OpenMP) -endif() - # FIXME: it should be PATH, but then it is escaped, and that breaks gtest set(UNITTEST_REPORT_PATH ${CMAKE_BINARY_DIR}/unittest-reports/ CACHE STRING "" FORCE) @@ -31,6 +27,7 @@ function(add_rs_test src) endfunction() add_subdirectory(common) +add_subdirectory(decompressors) add_subdirectory(io) add_subdirectory(metadata) add_subdirectory(test) diff --git a/src/external/rawspeed/test/librawspeed/common/CMakeLists.txt b/src/external/rawspeed/test/librawspeed/common/CMakeLists.txt index f0348252a..9bbb07539 100644 --- a/src/external/rawspeed/test/librawspeed/common/CMakeLists.txt +++ b/src/external/rawspeed/test/librawspeed/common/CMakeLists.txt @@ -1,4 +1,5 @@ FILE(GLOB RAWSPEED_TEST_SOURCES + "ChecksumFileTest.cpp" "CommonTest.cpp" "CpuidTest.cpp" "MemoryTest.cpp" diff --git a/src/external/rawspeed/test/librawspeed/common/ChecksumFileTest.cpp b/src/external/rawspeed/test/librawspeed/common/ChecksumFileTest.cpp new file mode 100644 index 000000000..1d742c711 --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/common/ChecksumFileTest.cpp @@ -0,0 +1,79 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; withexpected even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "common/ChecksumFile.h" // for ParseChecksumFileContent +#include "common/RawspeedException.h" // IWYU pragma: keep +#include <gtest/gtest.h> // for AssertionResult, Message, TestPartR... +#include <memory> // for allocator_traits<>::value_type +#include <string> // for allocator, operator+, string, basic... +#include <vector> // for vector + +using rawspeed::ParseChecksumFileContent; + +namespace rawspeed_test { + +TEST(ParseChecksumFileContentTest, Empty) { + const auto Content = ParseChecksumFileContent({}, {}); + ASSERT_TRUE(Content.empty()); +} + +TEST(ParseChecksumFileContentTest, ShortLine) { + auto gen = [](int len) { + return ParseChecksumFileContent(std::string(len, ' '), {}); + }; + EXPECT_THROW(gen(41), rawspeed::RawspeedException); + EXPECT_THROW(gen(42), rawspeed::RawspeedException); + EXPECT_NO_THROW(gen(43)); +} + +TEST(ParseChecksumFileContentTest, Lines) { + const auto OneLine = std::string(43, ' '); + + auto Content = ParseChecksumFileContent(OneLine, {}); + ASSERT_FALSE(Content.empty()); + ASSERT_EQ(Content.size(), 1); + + Content = ParseChecksumFileContent(OneLine + std::string("\n") + OneLine, {}); + ASSERT_FALSE(Content.empty()); + ASSERT_EQ(Content.size(), 2); + + Content = ParseChecksumFileContent( + OneLine + std::string("\n") + OneLine + std::string("\n"), {}); + ASSERT_FALSE(Content.empty()); + ASSERT_EQ(Content.size(), 2); +} + +TEST(ParseChecksumFileContentTest, TheTest) { + const std::string testLine = "0000000000000000000000000000000000000000 file"; + + auto Content = ParseChecksumFileContent(testLine, ""); + ASSERT_FALSE(Content.empty()); + ASSERT_EQ(Content.size(), 1); + ASSERT_EQ(Content.front().RelFileName, "file"); + ASSERT_EQ(Content.front().FullFileName, "/file"); + + Content = ParseChecksumFileContent(testLine, "dir"); + ASSERT_FALSE(Content.empty()); + ASSERT_EQ(Content.size(), 1); + ASSERT_EQ(Content.front().RelFileName, "file"); + ASSERT_EQ(Content.front().FullFileName, "dir/file"); +} + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/common/CommonTest.cpp b/src/external/rawspeed/test/librawspeed/common/CommonTest.cpp index a3b46079d..968e4254c 100644 --- a/src/external/rawspeed/test/librawspeed/common/CommonTest.cpp +++ b/src/external/rawspeed/test/librawspeed/common/CommonTest.cpp @@ -18,16 +18,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "common/Common.h" // for uchar8, clampBits, isIn, isPower... -#include <algorithm> // for fill, min, equal -#include <cassert> // for assert -#include <cstddef> // for size_t -#include <gtest/gtest.h> // for make_tuple, get, IsNullLiteralHe... -#include <limits> // for numeric_limits -#include <memory> // for unique_ptr -#include <string> // for basic_string, string, allocator -#include <vector> // for vector -// IWYU pragma: no_include <type_traits> +#include "common/Common.h" // for uchar8, clampBits, roundUp, isIn, isPowe... +#include <algorithm> // for fill, min, equal, generate_n +#include <cassert> // for assert +#include <cstddef> // for size_t +#include <gtest/gtest.h> // for make_tuple, get, ParamIteratorInterface +#include <initializer_list> // for initializer_list +#include <iterator> // for back_inserter +#include <limits> // for numeric_limits +#include <memory> // for make_unique, unique_ptr +#include <string> // for string, operator==, basic_string +#include <type_traits> // for __decay_and_strip<>::__type +#include <vector> // for vector using rawspeed::clampBits; using rawspeed::copyPixels; @@ -35,6 +37,7 @@ using rawspeed::getThreadCount; using rawspeed::isAligned; using rawspeed::isIn; using rawspeed::isPowerOfTwo; +using rawspeed::roundDown; using rawspeed::roundUp; using rawspeed::roundUpDivision; using rawspeed::splitString; @@ -50,13 +53,13 @@ using std::vector; namespace rawspeed_test { -using powerOfTwoType = std::tr1::tuple<int, bool>; +using powerOfTwoType = std::tuple<int, bool>; class PowerOfTwoTest : public ::testing::TestWithParam<powerOfTwoType> { protected: PowerOfTwoTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - expected = std::tr1::get<1>(GetParam()); + in = std::get<0>(GetParam()); + expected = std::get<1>(GetParam()); } int in; // input @@ -75,14 +78,42 @@ TEST_P(PowerOfTwoTest, PowerOfTwoTest) { ASSERT_EQ(isPowerOfTwo(in), expected); } -using RoundUpType = std::tr1::tuple<size_t, size_t, size_t>; +using RoundDownType = std::tuple<size_t, size_t, size_t>; +class RoundDownTest : public ::testing::TestWithParam<RoundDownType> { +protected: + RoundDownTest() = default; + virtual void SetUp() { + in = std::get<0>(GetParam()); + multiple = std::get<1>(GetParam()); + expected = std::get<2>(GetParam()); + } + + size_t in; // input + size_t multiple; + size_t expected; // expected output +}; +static const RoundDownType RoundDownValues[] = { + make_tuple(0, 0, 0), make_tuple(0, 10, 0), make_tuple(10, 0, 10), + make_tuple(10, 10, 10), make_tuple(10, 1, 10), make_tuple(10, 2, 10), + make_tuple(10, 3, 9), make_tuple(10, 4, 8), make_tuple(10, 5, 10), + make_tuple(10, 6, 6), make_tuple(10, 7, 7), make_tuple(10, 8, 8), + make_tuple(10, 9, 9), make_tuple(10, 11, 0), make_tuple(10, 12, 0), + +}; +INSTANTIATE_TEST_CASE_P(RoundDownTest, RoundDownTest, + ::testing::ValuesIn(RoundDownValues)); +TEST_P(RoundDownTest, RoundDownTest) { + ASSERT_EQ(roundDown(in, multiple), expected); +} + +using RoundUpType = std::tuple<size_t, size_t, size_t>; class RoundUpTest : public ::testing::TestWithParam<RoundUpType> { protected: RoundUpTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - multiple = std::tr1::get<1>(GetParam()); - expected = std::tr1::get<2>(GetParam()); + in = std::get<0>(GetParam()); + multiple = std::get<1>(GetParam()); + expected = std::get<2>(GetParam()); } size_t in; // input @@ -101,15 +132,15 @@ INSTANTIATE_TEST_CASE_P(RoundUpTest, RoundUpTest, ::testing::ValuesIn(RoundUpValues)); TEST_P(RoundUpTest, RoundUpTest) { ASSERT_EQ(roundUp(in, multiple), expected); } -using RoundUpDivisionType = std::tr1::tuple<size_t, size_t, size_t>; +using RoundUpDivisionType = std::tuple<size_t, size_t, size_t>; class RoundUpDivisionTest : public ::testing::TestWithParam<RoundUpDivisionType> { protected: RoundUpDivisionTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - divider = std::tr1::get<1>(GetParam()); - expected = std::tr1::get<2>(GetParam()); + in = std::get<0>(GetParam()); + divider = std::get<1>(GetParam()); + expected = std::get<2>(GetParam()); } size_t in; // input @@ -152,13 +183,13 @@ TEST_P(RoundUpDivisionTest, RoundUpDivisionTest) { ASSERT_EQ(roundUpDivision(in, divider), expected); } -using IsAlignedType = std::tr1::tuple<int, int>; +using IsAlignedType = std::tuple<int, int>; class IsAlignedTest : public ::testing::TestWithParam<IsAlignedType> { protected: IsAlignedTest() = default; virtual void SetUp() { - value = std::tr1::get<0>(GetParam()); - multiple = std::tr1::get<1>(GetParam()); + value = std::get<0>(GetParam()); + multiple = std::get<1>(GetParam()); } int value; @@ -171,13 +202,13 @@ TEST_P(IsAlignedTest, IsAlignedAfterRoundUpTest) { ASSERT_TRUE(isAligned(roundUp(value, multiple), multiple)); } -using IsInType = std::tr1::tuple<string, bool>; +using IsInType = std::tuple<string, bool>; class IsInTest : public ::testing::TestWithParam<IsInType> { protected: IsInTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - expected = std::tr1::get<1>(GetParam()); + in = std::get<0>(GetParam()); + expected = std::get<1>(GetParam()); } string in; // input @@ -196,14 +227,14 @@ TEST_P(IsInTest, IsInTest) { ASSERT_EQ(isIn(in, {"foo", "foo2", "bar", "baz"}), expected); } -using ClampBitsType = std::tr1::tuple<int, int, ushort16>; +using ClampBitsType = std::tuple<int, int, ushort16>; class ClampBitsTest : public ::testing::TestWithParam<ClampBitsType> { protected: ClampBitsTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - n = std::tr1::get<1>(GetParam()); - expected = std::tr1::get<2>(GetParam()); + in = std::get<0>(GetParam()); + n = std::get<1>(GetParam()); + expected = std::get<2>(GetParam()); } int in; // input @@ -245,17 +276,24 @@ INSTANTIATE_TEST_CASE_P(ClampBitsTest, ClampBitsTest, TEST_P(ClampBitsTest, ClampBitsTest) { ASSERT_EQ(clampBits(in, n), expected); } TEST(ClampBitsDeathTest, Only16Bit) { #ifndef NDEBUG - ASSERT_DEATH({ ASSERT_EQ(clampBits(0, 17), 0); }, "n <= 16"); + ASSERT_DEATH({ ASSERT_EQ(clampBits(0, 17), 0); }, "nBits <= 16"); +#endif +} + +TEST(ClampBitsUnsignedDeathTest, NoNopClamps) { +#ifndef NDEBUG + ASSERT_DEATH({ ASSERT_EQ(clampBits<ushort16>(0, 16), 0); }, + "BitWidthOfT > nBits"); #endif } -using TrimSpacesType = std::tr1::tuple<string, string>; +using TrimSpacesType = std::tuple<string, string>; class TrimSpacesTest : public ::testing::TestWithParam<TrimSpacesType> { protected: TrimSpacesTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - out = std::tr1::get<1>(GetParam()); + in = std::get<0>(GetParam()); + out = std::get<1>(GetParam()); } string in; // input @@ -285,14 +323,14 @@ INSTANTIATE_TEST_CASE_P(TrimSpacesTest, TrimSpacesTest, ::testing::ValuesIn(TrimSpacesValues)); TEST_P(TrimSpacesTest, TrimSpacesTest) { ASSERT_EQ(trimSpaces(in), out); } -using splitStringType = std::tr1::tuple<string, char, vector<string>>; +using splitStringType = std::tuple<string, char, vector<string>>; class SplitStringTest : public ::testing::TestWithParam<splitStringType> { protected: SplitStringTest() = default; virtual void SetUp() { - in = std::tr1::get<0>(GetParam()); - sep = std::tr1::get<1>(GetParam()); - out = std::tr1::get<2>(GetParam()); + in = std::get<0>(GetParam()); + sep = std::get<1>(GetParam()); + out = std::get<2>(GetParam()); } string in; // input @@ -386,15 +424,15 @@ TEST(MakeUniqueTest, Test) { }); } -using copyPixelsType = std::tr1::tuple<int, int, int, int>; +using copyPixelsType = std::tuple<int, int, int, int>; class CopyPixelsTest : public ::testing::TestWithParam<copyPixelsType> { protected: CopyPixelsTest() = default; virtual void SetUp() { - dstPitch = std::tr1::get<0>(GetParam()); - srcPitch = std::tr1::get<1>(GetParam()); - rowSize = min(min(std::tr1::get<2>(GetParam()), srcPitch), dstPitch); - height = std::tr1::get<3>(GetParam()); + dstPitch = std::get<0>(GetParam()); + srcPitch = std::get<1>(GetParam()); + rowSize = min(min(std::get<2>(GetParam()), srcPitch), dstPitch); + height = std::get<3>(GetParam()); assert(srcPitch * height < numeric_limits<uchar8>::max()); assert(dstPitch * height < numeric_limits<uchar8>::max()); @@ -403,7 +441,7 @@ protected: dst.resize((size_t)dstPitch * height); fill(src.begin(), src.end(), 0); - fill(dst.begin(), dst.end(), -1); + fill(dst.begin(), dst.end(), static_cast<decltype(dst)::value_type>(-1)); } void generate() { uchar8 v = 0; diff --git a/src/external/rawspeed/test/librawspeed/common/PointTest.cpp b/src/external/rawspeed/test/librawspeed/common/PointTest.cpp index 4d1621bc3..f89f490fd 100644 --- a/src/external/rawspeed/test/librawspeed/common/PointTest.cpp +++ b/src/external/rawspeed/test/librawspeed/common/PointTest.cpp @@ -18,10 +18,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "common/Point.h" // for iPoint2D -#include <gtest/gtest.h> // for make_tuple, AssertionResult, IsNullLiteral... +#include "common/Point.h" // for iPoint2D, iPoint2D::area_type, iPoint2D::v... +#include <algorithm> // for find +#include <gtest/gtest.h> // for make_tuple, Message, TestPartResult, get +#include <iterator> // for cend, cbegin #include <limits> // for numeric_limits #include <ostream> // for operator<<, basic_ostream::operator<<, ost... +#include <type_traits> // for __decay_and_strip<>::__type #include <utility> // for make_pair, pair, move using rawspeed::iPoint2D; @@ -144,20 +147,20 @@ TEST(PointTest, NonEqualityOperator) { } using IntPair = pair<int, int>; -using Six = std::tr1::tuple<IntPair, IntPair, IntPair>; +using Six = std::tuple<IntPair, IntPair, IntPair>; class PointTest : public ::testing::TestWithParam<Six> { protected: PointTest() = default; virtual void SetUp() { auto p = GetParam(); - auto pair = std::tr1::get<0>(p); + auto pair = std::get<0>(p); a = iPoint2D(pair.first, pair.second); - pair = std::tr1::get<1>(p); + pair = std::get<1>(p); b = iPoint2D(pair.first, pair.second); - pair = std::tr1::get<2>(p); + pair = std::get<2>(p); c = iPoint2D(pair.first, pair.second); } @@ -325,7 +328,7 @@ protected: HasPositiveAreaTest() = default; virtual void SetUp() { auto param = GetParam(); - p = {std::tr1::get<0>(param), std::tr1::get<1>(param)}; + p = {std::get<0>(param), std::get<1>(param)}; } iPoint2D p; @@ -356,10 +359,10 @@ protected: virtual void SetUp() { auto param = GetParam(); - auto pair = std::tr1::get<0>(param); + auto pair = std::get<0>(param); p = iPoint2D(pair.first, pair.second); - a = std::tr1::get<1>(param); + a = std::get<1>(param); } iPoint2D p; @@ -418,24 +421,24 @@ TEST_P(AreaTest, AreaTest) { } using operatorsType = - std::tr1::tuple<IntPair, IntPair, bool, bool, bool, bool, bool>; + std::tuple<IntPair, IntPair, bool, bool, bool, bool, bool>; class OperatorsTest : public ::testing::TestWithParam<operatorsType> { protected: OperatorsTest() = default; virtual void SetUp() { auto p = GetParam(); - auto pair = std::tr1::get<0>(p); + auto pair = std::get<0>(p); a = iPoint2D(pair.first, pair.second); - pair = std::tr1::get<1>(p); + pair = std::get<1>(p); b = iPoint2D(pair.first, pair.second); - eq = std::tr1::get<2>(p); - lt = std::tr1::get<3>(p); - gt = std::tr1::get<4>(p); - le = std::tr1::get<5>(p); - ge = std::tr1::get<6>(p); + eq = std::get<2>(p); + lt = std::get<3>(p); + gt = std::get<4>(p); + le = std::get<5>(p); + ge = std::get<6>(p); } iPoint2D a; diff --git a/src/external/rawspeed/test/librawspeed/common/RangeTest.h b/src/external/rawspeed/test/librawspeed/common/RangeTest.h index 79fe408ea..5e51fdc88 100644 --- a/src/external/rawspeed/test/librawspeed/common/RangeTest.h +++ b/src/external/rawspeed/test/librawspeed/common/RangeTest.h @@ -98,13 +98,13 @@ template <typename T> << rhs << ") do overlap."; } -using twoRangesType = std::tr1::tuple<int, unsigned, int, unsigned>; +using twoRangesType = std::tuple<int, unsigned, int, unsigned>; class TwoRangesTest : public ::testing::TestWithParam<twoRangesType> { protected: TwoRangesTest() = default; virtual void SetUp() { - r0 = Range<int>(std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam())); - r1 = Range<int>(std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam())); + r0 = Range<int>(std::get<0>(GetParam()), std::get<1>(GetParam())); + r1 = Range<int>(std::get<2>(GetParam()), std::get<3>(GetParam())); } Range<int> r0; diff --git a/src/external/rawspeed/test/librawspeed/common/SplineTest.cpp b/src/external/rawspeed/test/librawspeed/common/SplineTest.cpp index 06283d0c2..283854027 100644 --- a/src/external/rawspeed/test/librawspeed/common/SplineTest.cpp +++ b/src/external/rawspeed/test/librawspeed/common/SplineTest.cpp @@ -18,11 +18,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "common/Spline.h" // for Spline +#include "common/Spline.h" // for Spline, Spline<>::value_type +#include "common/Common.h" // for ushort16 +#include "common/Point.h" // for iPoint2D, iPoint2D::value_type +#include <algorithm> // for generate_n #include <array> // for array -#include <cmath> // for acos -#include <gtest/gtest.h> // for AssertionResult, DeathTest, Test, AssertHe... -#include <type_traits> // for is_same, enable_if_t, is_arithmetic +#include <cassert> // for assert +#include <cmath> // for lround, acos, sin +#include <gtest/gtest.h> // for make_tuple, ParamIteratorInterface, Message +#include <iterator> // for begin, end, back_inserter +#include <limits> // for numeric_limits +#include <ostream> // for operator<<, basic_ostream::operator<< +#include <stdlib.h> // for exit +#include <type_traits> // for __decay_and_strip<>::__type, enable_if_t +#include <vector> // for vector using rawspeed::Spline; using std::make_tuple; diff --git a/src/external/rawspeed/test/librawspeed/common/ThreadingTest.cpp b/src/external/rawspeed/test/librawspeed/common/ThreadingTest.cpp index 091cb631f..425cb8633 100644 --- a/src/external/rawspeed/test/librawspeed/common/ThreadingTest.cpp +++ b/src/external/rawspeed/test/librawspeed/common/ThreadingTest.cpp @@ -58,7 +58,7 @@ inline std::vector<unsigned> sliceUp_dumb(unsigned bucketsNum, return buckets; } -using twoValsType = std::tr1::tuple<unsigned, unsigned>; +using twoValsType = std::tuple<unsigned, unsigned>; static const std::map<twoValsType, std::array<unsigned, 4>> Expected{ {std::make_tuple(0U, 0U), {{}}}, @@ -103,8 +103,8 @@ class SliceUpTest : public ::testing::TestWithParam<twoValsType> { protected: SliceUpTest() = default; virtual void SetUp() { - threads = std::tr1::get<0>(GetParam()); - pieces = std::tr1::get<1>(GetParam()); + threads = std::get<0>(GetParam()); + pieces = std::get<1>(GetParam()); expected = Expected.find(GetParam()); ASSERT_NE(expected, Expected.end()); @@ -140,8 +140,8 @@ class SliceUpTortureTest : public ::testing::TestWithParam<twoValsType> { protected: SliceUpTortureTest() = default; virtual void SetUp() { - threads = std::tr1::get<0>(GetParam()); - pieces = std::tr1::get<1>(GetParam()); + threads = std::get<0>(GetParam()); + pieces = std::get<1>(GetParam()); } unsigned threads; diff --git a/src/external/rawspeed/test/librawspeed/decompressors/AbstractHuffmanTableTest.cpp b/src/external/rawspeed/test/librawspeed/decompressors/AbstractHuffmanTableTest.cpp new file mode 100644 index 000000000..549642fd3 --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/decompressors/AbstractHuffmanTableTest.cpp @@ -0,0 +1,655 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; withexpected even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "decompressors/AbstractHuffmanTable.h" // for AbstractHuffmanTable... +#include "common/Common.h" // for uchar8, uint32 +#include "io/Buffer.h" // for Buffer +#include <algorithm> // for min +#include <bitset> // for bitset +#include <cassert> // for assert +#include <cstdlib> // for exit +#include <gtest/gtest.h> // for make_tuple, Message +#include <initializer_list> // for initializer_list<>::... +#include <ostream> // for operator<<, ostream +#include <string> // for basic_string, operat... +#include <utility> // for move +#include <vector> // for vector + +using rawspeed::AbstractHuffmanTable; +using rawspeed::Buffer; +using rawspeed::uchar8; +using std::make_tuple; + +namespace rawspeed { + +class RawDecoderException; + +bool operator!=(const AbstractHuffmanTable& lhs, + const AbstractHuffmanTable& rhs) { + return !(lhs == rhs); +} + +::std::ostream& operator<<(::std::ostream& os, + const AbstractHuffmanTable::CodeSymbol s) { + auto str = std::bitset<32>(s.code).to_string(); + + str = str.substr(str.size() - s.code_len); + return os << "0b" << str; +} + +bool operator!=(const AbstractHuffmanTable::CodeSymbol& lhs, + const AbstractHuffmanTable::CodeSymbol& rhs) { + return !(lhs == rhs); +} + +} // namespace rawspeed + +namespace rawspeed_test { + +TEST(AbstractHuffmanTableCodeSymbolTest, Equality) { +#define s AbstractHuffmanTable::CodeSymbol + ASSERT_EQ(s(0, 1), s(0, 1)); + ASSERT_EQ(s(1, 1), s(1, 1)); + + ASSERT_NE(s(1, 1), s(0, 1)); + ASSERT_NE(s(0, 1), s(1, 1)); +#undef s +} + +#ifndef NDEBUG +TEST(CodeSymbolDeathTest, CodeSymbolLenght) { + ASSERT_DEATH({ AbstractHuffmanTable::CodeSymbol(0, 0); }, "code_len > 0"); + ASSERT_DEATH({ AbstractHuffmanTable::CodeSymbol(1, 0); }, "code_len > 0"); + ASSERT_DEATH({ AbstractHuffmanTable::CodeSymbol(0, 17); }, "code_len <= 16"); + ASSERT_DEATH({ AbstractHuffmanTable::CodeSymbol(1, 17); }, "code_len <= 16"); +} + +using CodeSymbolType = std::tuple<int, int, bool>; +class CodeSymbolDeathTest : public ::testing::TestWithParam<CodeSymbolType> { +protected: + CodeSymbolDeathTest() = default; + virtual void SetUp() { + auto p = GetParam(); + + val = std::get<0>(p); + len = std::get<1>(p); + die = std::get<2>(p); + } + + int val; + int len; + bool die; +}; +static const CodeSymbolType CodeSymbolData[]{ + // clang-format off + make_tuple(0b00, 1, false), + make_tuple(0b00, 2, false), + make_tuple(0b01, 1, false), + make_tuple(0b01, 2, false), + make_tuple(0b10, 1, true), + make_tuple(0b10, 2, false), + make_tuple(0b11, 1, true), + make_tuple(0b11, 2, false), + // clang-format on +}; +INSTANTIATE_TEST_CASE_P(CodeSymbolDeathTest, CodeSymbolDeathTest, + ::testing::ValuesIn(CodeSymbolData)); +TEST_P(CodeSymbolDeathTest, CodeSymbolDeathTest) { + if (die) { + ASSERT_DEATH({ AbstractHuffmanTable::CodeSymbol(val, len); }, + "code <= \\(\\(1U << code_len\\) - 1U\\)"); + } else { + ASSERT_EXIT( + { + AbstractHuffmanTable::CodeSymbol(val, len); + exit(0); + }, + ::testing::ExitedWithCode(0), ""); + } +} +#endif + +using CodeSymbolPrintDataType = std::tuple<int, int, std::string>; +class CodeSymbolPrintTest + : public ::testing::TestWithParam<CodeSymbolPrintDataType> { +protected: + CodeSymbolPrintTest() = default; + virtual void SetUp() { + auto p = GetParam(); + + val = std::get<0>(p); + len = std::get<1>(p); + str = std::get<2>(p); + } + + int val; + int len; + std::string str; +}; +static const CodeSymbolPrintDataType CodeSymbolPrintData[]{ + // clang-format off + make_tuple(0b00, 1, "0b0"), + make_tuple(0b00, 2, "0b00"), + make_tuple(0b01, 1, "0b1"), + make_tuple(0b01, 2, "0b01"), + make_tuple(0b10, 2, "0b10"), + make_tuple(0b11, 2, "0b11"), + // clang-format on +}; +INSTANTIATE_TEST_CASE_P(CodeSymbolPrintTest, CodeSymbolPrintTest, + ::testing::ValuesIn(CodeSymbolPrintData)); +TEST_P(CodeSymbolPrintTest, CodeSymbolPrintTest) { + ASSERT_EQ( + ::testing::PrintToString(AbstractHuffmanTable::CodeSymbol(val, len)), + str); +} + +using CodeSymbolHaveCommonPrefixDataType = + std::tuple<AbstractHuffmanTable::CodeSymbol, + AbstractHuffmanTable::CodeSymbol>; +class CodeSymbolHaveCommonPrefixTest + : public ::testing::TestWithParam<CodeSymbolHaveCommonPrefixDataType> { +protected: + CodeSymbolHaveCommonPrefixTest() = default; + virtual void SetUp() { + auto p = GetParam(); + + symbol = std::get<0>(p); + partial = std::get<1>(p); + } + + AbstractHuffmanTable::CodeSymbol symbol; + AbstractHuffmanTable::CodeSymbol partial; +}; +std::vector<AbstractHuffmanTable::CodeSymbol> GenerateAllPossibleCodeSymbols() { + // change those two together + static constexpr auto maxLen = 2U; + static constexpr auto expectedCnt = 2U + 4U; + + std::vector<AbstractHuffmanTable::CodeSymbol> allVariants; + allVariants.reserve(expectedCnt); + for (unsigned l = 1; l <= maxLen; l++) { + for (unsigned c = 0; c <= ((1U << l) - 1U); c++) + allVariants.emplace_back(c, l); + } + assert(allVariants.size() == expectedCnt); + return allVariants; +} +static const auto allPossibleCodeSymbols = GenerateAllPossibleCodeSymbols(); +INSTANTIATE_TEST_CASE_P( + CodeSymbolHaveCommonPrefixTest, CodeSymbolHaveCommonPrefixTest, + ::testing::Combine(::testing::ValuesIn(allPossibleCodeSymbols), + ::testing::ValuesIn(allPossibleCodeSymbols))); +TEST_P(CodeSymbolHaveCommonPrefixTest, CodeSymbolHaveCommonPrefixTest) { + if (partial.code_len > symbol.code_len) + return; + + auto symbol_str = ::testing::PrintToString(symbol); + auto partial_str = ::testing::PrintToString(partial); + const auto len = std::min(symbol_str.length(), partial_str.length()); + // Trim them to the same lenght (cut end chars) + symbol_str.resize(len); + partial_str.resize(len); + ASSERT_EQ(AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix(symbol, partial), + symbol_str == partial_str) + << "Where symbol_str = " << symbol_str + << ", partial_str = " << partial_str; +} +TEST(CodeSymbolHaveCommonPrefixTest, BasicTest) { + { + // Self-check for common prefix equals true + const AbstractHuffmanTable::CodeSymbol s(0b0, 1); + ASSERT_TRUE(AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix(s, s)); + } + ASSERT_TRUE( + AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix({0b0, 1}, {0b0, 1})); + ASSERT_TRUE( + AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix({0b10, 2}, {0b1, 1})); + ASSERT_FALSE( + AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix({0b10, 2}, {0b0, 1})); + ASSERT_FALSE( + AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix({0b10, 2}, {0b01, 2})); +} + +#ifndef NDEBUG +TEST(CodeSymbolHaveCommonPrefixDeathTest, AsymmetricalDeathTest) { + ASSERT_DEATH( + { + AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix({0b0, 1}, {0b0, 2}); + }, + "partial.code_len <= symbol.code_len"); + ASSERT_DEATH( + { + AbstractHuffmanTable::CodeSymbol::HaveCommonPrefix({0b01, 2}, + {0b010, 3}); + }, + "partial.code_len <= symbol.code_len"); +} +#endif + +auto genHT = [](std::initializer_list<uchar8>&& nCodesPerLength) + -> AbstractHuffmanTable { + AbstractHuffmanTable ht; + std::vector<uchar8> v(nCodesPerLength.begin(), nCodesPerLength.end()); + v.resize(16); + Buffer b(v.data(), v.size()); + ht.setNCodesPerLength(b); + + return ht; +}; + +auto genHTCount = + [](std::initializer_list<uchar8>&& nCodesPerLength) -> rawspeed::uint32 { + AbstractHuffmanTable ht; + std::vector<uchar8> v(nCodesPerLength.begin(), nCodesPerLength.end()); + v.resize(16); + Buffer b(v.data(), v.size()); + return ht.setNCodesPerLength(b); +}; + +auto genHTFull = + [](std::initializer_list<uchar8>&& nCodesPerLength, + std::initializer_list<uchar8>&& codeValues) -> AbstractHuffmanTable { + auto ht = genHT(std::move(nCodesPerLength)); + std::vector<uchar8> v(codeValues.begin(), codeValues.end()); + Buffer b(v.data(), v.size()); + ht.setCodeValues(b); + return ht; +}; + +#ifndef NDEBUG +TEST(AbstractHuffmanTableDeathTest, setNCodesPerLengthRequires16Lengths) { + for (int i = 0; i < 32; i++) { + std::vector<uchar8> v(i, 1); + ASSERT_EQ(v.size(), i); + + Buffer b(v.data(), v.size()); + ASSERT_EQ(b.getSize(), v.size()); + + AbstractHuffmanTable ht; + + if (b.getSize() != 16) { + ASSERT_DEATH({ ht.setNCodesPerLength(b); }, "data.getSize\\(\\) == 16"); + } else { + ASSERT_EXIT( + { + ht.setNCodesPerLength(b); + + exit(0); + }, + ::testing::ExitedWithCode(0), ""); + } + } +} +#endif + +TEST(AbstractHuffmanTableTest, setNCodesPerLengthEqualCompareAndTrimming) { + { + AbstractHuffmanTable a; + AbstractHuffmanTable b; + + ASSERT_EQ(a, b); + } + + ASSERT_EQ(genHT({1}), genHT({1})); + ASSERT_EQ(genHT({1}), genHT({1, 0})); + ASSERT_EQ(genHT({1, 0}), genHT({1})); + ASSERT_EQ(genHT({1, 0}), genHT({1, 0})); + ASSERT_EQ(genHT({0, 1}), genHT({0, 1})); + ASSERT_EQ(genHT({1, 1}), genHT({1, 1})); + + ASSERT_NE(genHT({1, 0}), genHT({1, 1})); + ASSERT_NE(genHT({0, 1}), genHT({1})); + ASSERT_NE(genHT({0, 1}), genHT({1, 0})); + ASSERT_NE(genHT({0, 1}), genHT({1, 1})); + ASSERT_NE(genHT({1}), genHT({1, 1})); +} + +TEST(AbstractHuffmanTableTest, setNCodesPerLengthEmptyIsBad) { + ASSERT_THROW(genHT({}), rawspeed::RawDecoderException); + ASSERT_THROW(genHT({0}), rawspeed::RawDecoderException); + ASSERT_THROW(genHT({0, 0}), rawspeed::RawDecoderException); +} + +TEST(AbstractHuffmanTableTest, setNCodesPerLengthTooManyCodesTotal) { + ASSERT_NO_THROW(genHT({0, 0, 0, 0, 0, 0, 0, 162})); + ASSERT_THROW(genHT({0, 0, 0, 0, 0, 0, 0, 163}), + rawspeed::RawDecoderException); +} + +TEST(AbstractHuffmanTableTest, setNCodesPerLengthTooManyCodesForLenght) { + for (int len = 1; len < 8; len++) { + AbstractHuffmanTable ht; + std::vector<uchar8> v(16, 0); + Buffer b(v.data(), v.size()); + for (auto i = 1U; i <= (1U << len); i++) { + v[len - 1] = i; + ASSERT_NO_THROW(ht.setNCodesPerLength(b);); + } + v[len - 1]++; + ASSERT_THROW(ht.setNCodesPerLength(b), rawspeed::RawDecoderException); + } +} + +TEST(AbstractHuffmanTableTest, setNCodesPerLengthCodeSymbolOverflow) { + ASSERT_NO_THROW(genHT({1})); + ASSERT_NO_THROW(genHT({2})); + ASSERT_THROW(genHT({3}), rawspeed::RawDecoderException); + ASSERT_NO_THROW(genHT({1, 2})); + ASSERT_THROW(genHT({1, 3}), rawspeed::RawDecoderException); + ASSERT_THROW(genHT({2, 1}), rawspeed::RawDecoderException); + ASSERT_NO_THROW(genHT({0, 4})); + ASSERT_THROW(genHT({0, 5}), rawspeed::RawDecoderException); +} + +TEST(AbstractHuffmanTableTest, setNCodesPerLengthCounts) { + ASSERT_EQ(genHTCount({1}), 1); + ASSERT_EQ(genHTCount({1, 0}), 1); + ASSERT_EQ(genHTCount({0, 1}), 1); + ASSERT_EQ(genHTCount({0, 2}), 2); + ASSERT_EQ(genHTCount({0, 3}), 3); + ASSERT_EQ(genHTCount({1, 1}), 2); + ASSERT_EQ(genHTCount({1, 2}), 3); +} + +#ifndef NDEBUG +TEST(AbstractHuffmanTableDeathTest, setCodeValuesRequiresCount) { + for (int len = 1; len < 8; len++) { + AbstractHuffmanTable ht; + std::vector<uchar8> l(16, 0); + Buffer bl(l.data(), l.size()); + l[len - 1] = (1U << len) - 1U; + const auto count = ht.setNCodesPerLength(bl); + std::vector<uchar8> v; + v.reserve(count + 1); + for (auto cnt = count - 1; cnt <= count + 1; cnt++) { + v.resize(cnt); + Buffer bv(v.data(), v.size()); + if (cnt != count) { + ASSERT_DEATH({ ht.setCodeValues(bv); }, + "data.getSize\\(\\) == maxCodesCount\\(\\)"); + } else { + ASSERT_EXIT( + { + ht.setCodeValues(bv); + exit(0); + }, + ::testing::ExitedWithCode(0), ""); + } + } + } +} + +TEST(AbstractHuffmanTableDeathTest, setCodeValuesRequiresLessThan162) { + auto ht = genHT({0, 0, 0, 0, 0, 0, 0, 162}); + std::vector<uchar8> v(163, 0); + Buffer bv(v.data(), v.size()); + ASSERT_DEATH({ ht.setCodeValues(bv); }, "data.getSize\\(\\) <= 162"); +} +#endif + +TEST(AbstractHuffmanTableTest, setCodeValuesValueLessThan16) { + auto ht = genHT({1}); + std::vector<uchar8> v(1); + + for (int i = 0; i < 256; i++) { + v[0] = i; + Buffer b(v.data(), v.size()); + if (i <= 16) + ASSERT_NO_THROW(ht.setCodeValues(b);); + else + ASSERT_THROW(ht.setCodeValues(b), rawspeed::RawDecoderException); + } +} + +TEST(AbstractHuffmanTableTest, EqualCompareAndTrimming) { + ASSERT_EQ(genHTFull({1}, {0}), genHTFull({1}, {0})); + ASSERT_EQ(genHTFull({1}, {1}), genHTFull({1}, {1})); + + ASSERT_EQ(genHTFull({1}, {0}), genHTFull({1, 0}, {0})); + ASSERT_EQ(genHTFull({1, 0}, {0}), genHTFull({1, 0}, {0})); + ASSERT_EQ(genHTFull({1, 0}, {0}), genHTFull({1}, {0})); + + ASSERT_NE(genHTFull({1}, {0}), genHTFull({1}, {1})); + ASSERT_NE(genHTFull({1}, {1}), genHTFull({1}, {0})); + + ASSERT_NE(genHTFull({1}, {0}), genHTFull({1, 0}, {1})); + ASSERT_NE(genHTFull({1, 0}, {0}), genHTFull({1, 0}, {1})); + ASSERT_NE(genHTFull({1, 0}, {0}), genHTFull({1}, {1})); +} + +using SignExtendDataType = std::tuple<rawspeed::uint32, rawspeed::uint32, int>; +class SignExtendTest : public ::testing::TestWithParam<SignExtendDataType> { +protected: + SignExtendTest() = default; + virtual void SetUp() { + auto p = GetParam(); + + diff = std::get<0>(p); + len = std::get<1>(p); + value = std::get<2>(p); + } + + rawspeed::uint32 diff; + rawspeed::uint32 len; + int value; +}; + +auto zeroDiff = [](int len) { return make_tuple(0, len, -((1 << len) - 1)); }; +auto passthrough = [](int len) { + return make_tuple(((1 << len) - 1), len, ((1 << len) - 1)); +}; +auto one = [](int len) { return make_tuple((1 << len), len, 1); }; +static const SignExtendDataType signExtendData[]{ + // clang-format off + zeroDiff(1), + zeroDiff(2), + zeroDiff(3), + zeroDiff(4), + zeroDiff(5), + zeroDiff(6), + zeroDiff(7), + zeroDiff(8), + zeroDiff(9), + zeroDiff(10), + zeroDiff(11), + zeroDiff(12), + zeroDiff(13), + zeroDiff(14), + zeroDiff(15), + zeroDiff(16), + + passthrough(1), + passthrough(2), + passthrough(3), + passthrough(4), + passthrough(5), + passthrough(6), + passthrough(7), + passthrough(8), + passthrough(9), + passthrough(10), + passthrough(11), + passthrough(12), + passthrough(13), + passthrough(14), + passthrough(15), + passthrough(16), + + one(1), + one(2), + one(3), + one(4), + one(5), + one(6), + one(7), + one(8), + one(9), + one(10), + one(11), + one(12), + one(13), + one(14), + one(15), + one(16), + + make_tuple(0b00, 0b01, -0b001), + make_tuple(0b01, 0b01, 0b001), + make_tuple(0b10, 0b01, 0b001), + make_tuple(0b11, 0b01, 0b011), + make_tuple(0b00, 0b10, -0b011), + make_tuple(0b01, 0b10, -0b010), + make_tuple(0b10, 0b10, 0b010), + make_tuple(0b11, 0b10, 0b011), + make_tuple(0b00, 0b11, -0b111), + make_tuple(0b01, 0b11, -0b110), + make_tuple(0b10, 0b11, -0b101), + make_tuple(0b11, 0b11, -0b100), + // clang-format on +}; +INSTANTIATE_TEST_CASE_P(SignExtendTest, SignExtendTest, + ::testing::ValuesIn(signExtendData)); +TEST_P(SignExtendTest, SignExtendTest) { + ASSERT_EQ(AbstractHuffmanTable::signExtended(diff, len), value); +} + +using generateCodeSymbolsDataType = + std::tuple<std::vector<uchar8>, + std::vector<AbstractHuffmanTable::CodeSymbol>>; +class generateCodeSymbolsTest + : protected AbstractHuffmanTable, + public ::testing::TestWithParam<generateCodeSymbolsDataType> { +protected: + generateCodeSymbolsTest() = default; + virtual void SetUp() { + auto p = GetParam(); + + ncpl = std::get<0>(p); + ncpl.resize(16); + expectedSymbols = std::get<1>(p); + } + + std::vector<uchar8> ncpl; + std::vector<AbstractHuffmanTable::CodeSymbol> expectedSymbols; +}; +static const generateCodeSymbolsDataType generateCodeSymbolsData[]{ + make_tuple(std::vector<rawspeed::uchar8>{1}, + std::vector<AbstractHuffmanTable::CodeSymbol>{{0b0, 1}}), + + make_tuple(std::vector<rawspeed::uchar8>{0, 1}, + std::vector<AbstractHuffmanTable::CodeSymbol>{ + {0b00, 2}, + }), + make_tuple(std::vector<rawspeed::uchar8>{0, 2}, + std::vector<AbstractHuffmanTable::CodeSymbol>{ + {0b00, 2}, + {0b01, 2}, + }), + make_tuple(std::vector<rawspeed::uchar8>{0, 3}, + std::vector<AbstractHuffmanTable::CodeSymbol>{ + {0b00, 2}, + {0b01, 2}, + {0b10, 2}, + }), + + make_tuple(std::vector<rawspeed::uchar8>{1, 1}, + std::vector<AbstractHuffmanTable::CodeSymbol>{ + {0b0, 1}, + {0b10, 2}, + }), + make_tuple(std::vector<rawspeed::uchar8>{1, 2}, + std::vector<AbstractHuffmanTable::CodeSymbol>{ + {0b0, 1}, + {0b10, 2}, + {0b11, 2}, + }), + +}; +INSTANTIATE_TEST_CASE_P(generateCodeSymbolsTest, generateCodeSymbolsTest, + ::testing::ValuesIn(generateCodeSymbolsData)); +TEST_P(generateCodeSymbolsTest, generateCodeSymbolsTest) { + Buffer bl(ncpl.data(), ncpl.size()); + const auto cnt = setNCodesPerLength(bl); + std::vector<uchar8> cv(cnt, 0); + Buffer bv(cv.data(), cv.size()); + setCodeValues(bv); + + ASSERT_EQ(generateCodeSymbols(), expectedSymbols); +} + +class DummyHuffmanTableTest : public AbstractHuffmanTable, + public ::testing::Test {}; +using DummyHuffmanTableDeathTest = DummyHuffmanTableTest; + +#ifndef NDEBUG +TEST_F(DummyHuffmanTableDeathTest, VerifyCodeSymbolsTest) { + { + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b0, 1}}; + ASSERT_EXIT( + { + VerifyCodeSymbols(s); + + exit(0); + }, + ::testing::ExitedWithCode(0), ""); + } + { + // Duplicates are not ok. + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b0, 1}, {0b0, 1}}; + ASSERT_DEATH({ VerifyCodeSymbols(s); }, + "all code symbols are globally ordered"); + } + { + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b0, 1}, {0b1, 1}}; + ASSERT_EXIT( + { + VerifyCodeSymbols(s); + + exit(0); + }, + ::testing::ExitedWithCode(0), ""); + } + { + // Code Symbols are strictly increasing + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b1, 1}, {0b0, 1}}; + ASSERT_DEATH({ VerifyCodeSymbols(s); }, + "all code symbols are globally ordered"); + } + { + // Code Lenghts are not decreasing + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b0, 2}, {0b1, 1}}; + ASSERT_DEATH({ VerifyCodeSymbols(s); }, + "all code symbols are globally ordered"); + } + { + // Reverse order + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b10, 2}, {0b0, 1}}; + ASSERT_DEATH({ VerifyCodeSymbols(s); }, + "all code symbols are globally ordered"); + } + { + // Can not have common prefixes + std::vector<AbstractHuffmanTable::CodeSymbol> s{{0b0, 1}, {0b01, 2}}; + ASSERT_DEATH({ VerifyCodeSymbols(s); }, "!CodeSymbol::HaveCommonPrefix"); + } +} +#endif + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/decompressors/BinaryHuffmanTreeTest.cpp b/src/external/rawspeed/test/librawspeed/decompressors/BinaryHuffmanTreeTest.cpp new file mode 100644 index 000000000..557a1dded --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/decompressors/BinaryHuffmanTreeTest.cpp @@ -0,0 +1,243 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; withexpected even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "decompressors/BinaryHuffmanTree.h" // for BinaryHuffmanTree, Bina... +#include <cstdlib> // for exit +#include <gtest/gtest.h> // for AssertionResult, Message +#include <initializer_list> // for initializer_list +#include <memory> // for unique_ptr, make_unique +#include <vector> // for vector + +using rawspeed::BinaryHuffmanTree; + +namespace rawspeed_test { + +TEST(BinaryHuffmanTreeTest, EmptyByDefault) { + { + const BinaryHuffmanTree<int> b; + ASSERT_FALSE(b.root); + } + { + BinaryHuffmanTree<int> b; + ASSERT_FALSE(b.root); + } + { + struct T { + int i; + }; + const BinaryHuffmanTree<T> b; + ASSERT_FALSE(b.root); + } +} + +#ifndef NDEBUG +TEST(BinaryHuffmanTreeDeathTest, getAllBranchesOfNegativeDepth) { + ASSERT_DEATH( + { + BinaryHuffmanTree<int> b; + b.getAllBranchesOfDepth(-1); + exit(0); + }, + "depth >= 0"); +} +#endif + +TEST(BinaryHuffmanTreeTest, getAllBranchesOfDepth_0_Base) { + BinaryHuffmanTree<int> b; + const auto zero = b.getAllBranchesOfDepth(0); + ASSERT_EQ(zero.size(), 1); + ASSERT_EQ(static_cast<typename decltype(b)::Node::Type>(*(b.root)), + decltype(b)::Node::Type::Branch); + ASSERT_FALSE(b.root->getAsBranch().hasLeafs()); + for (const auto& branch : zero) { + ASSERT_EQ(static_cast<typename decltype(b)::Node::Type>(*branch), + decltype(b)::Node::Type::Branch); + ASSERT_FALSE(branch->hasLeafs()); + } + ASSERT_EQ(zero[0], b.root.get()); +} +TEST(BinaryHuffmanTreeTest, getAllBranchesOfDepth_1_Base) { + BinaryHuffmanTree<int> b; + const auto one = b.getAllBranchesOfDepth(1); + ASSERT_EQ(one.size(), 2); + ASSERT_EQ(static_cast<typename decltype(b)::Node::Type>(*(b.root)), + decltype(b)::Node::Type::Branch); + ASSERT_FALSE(b.root->getAsBranch().hasLeafs()); + for (const auto& branch : one) { + ASSERT_EQ(static_cast<typename decltype(b)::Node::Type>(*branch), + decltype(b)::Node::Type::Branch); + ASSERT_FALSE(branch->hasLeafs()); + } + ASSERT_EQ(one[0], &(b.root->getAsBranch().zero->getAsBranch())); + ASSERT_EQ(one[1], &(b.root->getAsBranch().one->getAsBranch())); +} + +#ifndef NDEBUG +TEST(BinaryHuffmanTreeDeathTest, getAllNodesAtZeroDepth) { + ASSERT_DEATH( + { + BinaryHuffmanTree<int> b; + b.getAllVacantNodesAtDepth(0); + exit(0); + }, + "depth > 0"); +} +#endif + +TEST(BinaryHuffmanTreeTest, getAllVacantNodesAtDepth_1_Base) { + BinaryHuffmanTree<int> b; + const auto one = b.getAllVacantNodesAtDepth(1); + ASSERT_EQ(one.size(), 2); + ASSERT_EQ(one[0], &(b.root->getAsBranch().zero)); + ASSERT_EQ(one[1], &(b.root->getAsBranch().one)); +} + +TEST(BinaryHuffmanTreeTest, + getAllVacantNodesAtDepth_2_fills_depth_1_with_branches) { + BinaryHuffmanTree<int> b; + { + const auto one = b.getAllVacantNodesAtDepth(1); + ASSERT_EQ(one.size(), 2); + } + const auto two = b.getAllVacantNodesAtDepth(2); + ASSERT_EQ(two.size(), 4); + { + // All vacant nodes on previous depths are auto-filled with Branches + const auto one = b.getAllVacantNodesAtDepth(1); + ASSERT_EQ(one.size(), 0); + } +} + +TEST(BinaryHuffmanTreeTest, getAllVacantNodesAtDepth_2_Base) { + BinaryHuffmanTree<int> b; + const auto two = b.getAllVacantNodesAtDepth(2); + ASSERT_EQ(two.size(), 4); + ASSERT_EQ(two[0], &(b.root->getAsBranch().zero->getAsBranch().zero)); + ASSERT_EQ(two[1], &(b.root->getAsBranch().zero->getAsBranch().one)); + ASSERT_EQ(two[2], &(b.root->getAsBranch().one->getAsBranch().zero)); + ASSERT_EQ(two[3], &(b.root->getAsBranch().one->getAsBranch().one)); +} + +TEST(BinaryHuffmanTreeTest, pruneLeaflessBranches_purges_all) { + BinaryHuffmanTree<int> b; + b.getAllVacantNodesAtDepth(2); + ASSERT_TRUE(b.root); + b.pruneLeaflessBranches(); + ASSERT_FALSE(b.root); +} + +TEST(BinaryHuffmanTreeTest, + getAllVacantNodesAtDepth_1_after_adding_1_depth_1_leaf) { + BinaryHuffmanTree<int> b; + { + const auto one = b.getAllVacantNodesAtDepth(1); + ASSERT_EQ(one.size(), 2); + ASSERT_FALSE(b.root->getAsBranch().hasLeafs()); + // Add one leaf at the depth of one + *one.front() = std::make_unique<decltype(b)::Leaf>(); + ASSERT_TRUE(b.root->getAsBranch().hasLeafs()); + + // Now let's try pruning + b.pruneLeaflessBranches(); + ASSERT_TRUE(b.root); + ASSERT_TRUE(b.root->getAsBranch().hasLeafs()); + } + { + const auto one = b.getAllVacantNodesAtDepth(1); + ASSERT_EQ(one.size(), 1); + ASSERT_EQ(one[0], &(b.root->getAsBranch().one)); + } +} + +TEST(BinaryHuffmanTreeTest, + getAllVacantNodesAtDepth_2_after_adding_1_depth_1_leaf) { + BinaryHuffmanTree<int> b; + { + const auto two = b.getAllVacantNodesAtDepth(2); + ASSERT_EQ(two.size(), 4); + ASSERT_TRUE(b.root); + ASSERT_FALSE(b.root->getAsBranch().hasLeafs()); + ASSERT_TRUE(b.root->getAsBranch().zero); + ASSERT_TRUE(b.root->getAsBranch().one); + ASSERT_FALSE(b.root->getAsBranch().zero->getAsBranch().hasLeafs()); + ASSERT_FALSE(b.root->getAsBranch().one->getAsBranch().hasLeafs()); + + // Add one leaf at the depth of two + *two.front() = std::make_unique<decltype(b)::Leaf>(); + + ASSERT_TRUE(b.root); + ASSERT_FALSE(b.root->getAsBranch().hasLeafs()); + ASSERT_TRUE(b.root->getAsBranch().zero); + ASSERT_TRUE(b.root->getAsBranch().one); + ASSERT_TRUE(b.root->getAsBranch().zero->getAsBranch().hasLeafs()); + ASSERT_FALSE(b.root->getAsBranch().one->getAsBranch().hasLeafs()); + } + { + const auto two = b.getAllVacantNodesAtDepth(2); + ASSERT_EQ(two.size(), 3); + ASSERT_EQ(two[0], &(b.root->getAsBranch().zero->getAsBranch().one)); + ASSERT_EQ(two[1], &(b.root->getAsBranch().one->getAsBranch().zero)); + ASSERT_EQ(two[2], &(b.root->getAsBranch().one->getAsBranch().one)); + } + { + // And prune + b.pruneLeaflessBranches(); + ASSERT_TRUE(b.root); + ASSERT_FALSE(b.root->getAsBranch().hasLeafs()); + ASSERT_TRUE(b.root->getAsBranch().zero); + ASSERT_FALSE(b.root->getAsBranch().one); + ASSERT_TRUE(b.root->getAsBranch().zero->getAsBranch().hasLeafs()); + } +} + +TEST(BinaryHuffmanTreeTest, + getAllVacantNodesAtDepth_2_after_adding_1_depth_1_and_1_depth_2_leaf) { + BinaryHuffmanTree<int> b; + { + const auto one = b.getAllVacantNodesAtDepth(1); + ASSERT_EQ(one.size(), 2); + // Add one leaf at the depth of one + *one.front() = std::make_unique<decltype(b)::Leaf>(); + } + { + const auto two = b.getAllVacantNodesAtDepth(2); + ASSERT_EQ(two.size(), 2); + // Add one leaf at the depth of two + *two.front() = std::make_unique<decltype(b)::Leaf>(); + } + { + const auto two = b.getAllVacantNodesAtDepth(2); + ASSERT_EQ(two.size(), 1); + ASSERT_EQ(two[0], &(b.root->getAsBranch().one->getAsBranch().one)); + } + { + // And prune + b.pruneLeaflessBranches(); + ASSERT_TRUE(b.root); + ASSERT_TRUE(b.root->getAsBranch().hasLeafs()); + ASSERT_TRUE(b.root->getAsBranch().zero); + ASSERT_TRUE(b.root->getAsBranch().one); + ASSERT_TRUE(b.root->getAsBranch().one->getAsBranch().hasLeafs()); + ASSERT_TRUE(b.root->getAsBranch().one->getAsBranch().zero); + ASSERT_FALSE(b.root->getAsBranch().one->getAsBranch().one); + } +} + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/decompressors/CMakeLists.txt b/src/external/rawspeed/test/librawspeed/decompressors/CMakeLists.txt new file mode 100644 index 000000000..7d4a5cfdf --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/decompressors/CMakeLists.txt @@ -0,0 +1,9 @@ +FILE(GLOB RAWSPEED_TEST_SOURCES + "AbstractHuffmanTableTest.cpp" + "BinaryHuffmanTreeTest.cpp" + "HuffmanTableTest.cpp" +) + +foreach(IN ${RAWSPEED_TEST_SOURCES}) + add_rs_test(${IN}) +endforeach() diff --git a/src/external/rawspeed/test/librawspeed/decompressors/HuffmanTableTest.cpp b/src/external/rawspeed/test/librawspeed/decompressors/HuffmanTableTest.cpp new file mode 100644 index 000000000..22cf1f7b9 --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/decompressors/HuffmanTableTest.cpp @@ -0,0 +1,133 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; withexpected even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "decompressors/HuffmanTable.h" // for HuffmanTableLUT, HuffmanTable +#include "common/Common.h" // for uchar8 +#include "io/BitPumpMSB.h" // for BitPumpMSB, BitStream<>::fil... +#include "io/Buffer.h" // for Buffer, DataBuffer +#include "io/ByteStream.h" // for ByteStream +#include "io/Endianness.h" // for Endianness, Endianness::little +#include <array> // for array +#include <gtest/gtest.h> // for Test, Message, TestPartResult +#include <initializer_list> // for initializer_list<>::const_it... +#include <utility> // for move +#include <vector> // for vector + +namespace rawspeed { +class RawDecoderException; +} + +using rawspeed::BitPumpMSB; +using rawspeed::Buffer; +using rawspeed::ByteStream; +using rawspeed::DataBuffer; +using rawspeed::Endianness; +using rawspeed::HuffmanTable; +using rawspeed::uchar8; + +namespace rawspeed_test { + +auto genHT = + [](std::initializer_list<uchar8>&& nCodesPerLength) -> HuffmanTable { + HuffmanTable ht; + std::vector<uchar8> v(nCodesPerLength.begin(), nCodesPerLength.end()); + v.resize(16); + Buffer b(v.data(), v.size()); + ht.setNCodesPerLength(b); + + return ht; +}; + +auto genHTFull = + [](std::initializer_list<uchar8>&& nCodesPerLength, + std::initializer_list<uchar8>&& codeValues) -> HuffmanTable { + auto ht = genHT(std::move(nCodesPerLength)); + std::vector<uchar8> v(codeValues.begin(), codeValues.end()); + Buffer b(v.data(), v.size()); + ht.setCodeValues(b); + return ht; +}; + +TEST(HuffmanTableTest, DecodeLengthIdentityTest) { + static const std::array<rawspeed::uchar8, 4> data{ + {0b01010101, 0b01010101, 0b01010101, 0b01010101}}; + const Buffer b(data.data(), data.size()); + const DataBuffer db(b, Endianness::little); + const ByteStream bs(db); + + BitPumpMSB p(bs); + + auto ht = genHTFull({2}, {4, 8}); + ht.setup(false, false); + + for (int i = 0; i < 32; i += 2) { + ASSERT_EQ(ht.decodeLength(p), 4); + ASSERT_EQ(ht.decodeLength(p), 8); + } +} + +TEST(HuffmanTableTest, DecodeNextIdentityTest) { + static const std::array<rawspeed::uchar8, 4> data{ + {0b00000000, 0b11010101, 0b01010101, 0b01111111}}; + const Buffer b(data.data(), data.size()); + const DataBuffer db(b, Endianness::little); + const ByteStream bs(db); + + BitPumpMSB p(bs); + + auto ht = genHTFull({2}, {7, 7 + 8}); + ht.setup(true, false); + + ASSERT_EQ(ht.decodeNext(p), -127); + ASSERT_EQ(ht.decodeNext(p), 21845); + ASSERT_EQ(ht.decodeNext(p), 127); +} + +TEST(HuffmanTableTest, DecodeLengthBadCodeTest) { + static const std::array<rawspeed::uchar8, 4> data{{0b01000000}}; + const Buffer b(data.data(), data.size()); + const DataBuffer db(b, Endianness::little); + const ByteStream bs(db); + + BitPumpMSB p(bs); + + auto ht = genHTFull({1}, {4}); + ht.setup(false, false); + + ASSERT_EQ(ht.decodeLength(p), 4); + ASSERT_THROW(ht.decodeLength(p), rawspeed::RawDecoderException); +} + +TEST(HuffmanTableTest, DecodeNextBadCodeTest) { + static const std::array<rawspeed::uchar8, 4> data{{0b00100000}}; + const Buffer b(data.data(), data.size()); + const DataBuffer db(b, Endianness::little); + const ByteStream bs(db); + + BitPumpMSB p(bs); + + auto ht = genHTFull({1}, {1}); + ht.setup(true, false); + + ASSERT_EQ(ht.decodeNext(p), -1); + ASSERT_THROW(ht.decodeNext(p), rawspeed::RawDecoderException); +} + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/BitPumpJPEGTest.cpp b/src/external/rawspeed/test/librawspeed/io/BitPumpJPEGTest.cpp new file mode 100644 index 000000000..1936e2fd0 --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/io/BitPumpJPEGTest.cpp @@ -0,0 +1,110 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "io/BitPumpJPEG.h" // for BitPumpJPEG, BitStream<>::fillCache +#include "common/Common.h" // for uchar8, uint32 +#include "io/BitPumpTest.h" // for Endianness, Pattern, (anonymous), Buffer +#include "io/Buffer.h" // for Buffer, DataBuffer +#include "io/ByteStream.h" // for ByteStream +#include "io/Endianness.h" // for Endianness, Endianness::big, Endianness:... +#include <array> // for array +#include <gtest/gtest.h> // for Test, Message, TestInfo (ptr only), ASSE... +#include <initializer_list> // for initializer_list + +using rawspeed::BitPumpJPEG; +using rawspeed::Buffer; +using rawspeed::ByteStream; +using rawspeed::DataBuffer; +using rawspeed::Endianness; + +namespace rawspeed_test { + +struct InvOnesTag; +struct OnesTag; +struct SaturatedTag; + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpJPEG, OnesTag>::Data = { + {/* [Byte0 Byte1 Byte2 Byte3] */ + /* Byte: [Bit0 .. Bit7] */ + 0b10100100, 0b01000010, 0b00001000, 0b00011111}}; +template <> rawspeed::uint32 Pattern<BitPumpJPEG, OnesTag>::data(int index) { + const auto set = GenOnesBE(1, 0); + return set[index]; +} + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpJPEG, InvOnesTag>::Data = { + {0b11010010, 0b00100001, 0b00000100, 0b00001111}}; +template <> rawspeed::uint32 Pattern<BitPumpJPEG, InvOnesTag>::data(int index) { + const auto set = GenOnesBE(0, -1); + return set[index]; +} + +// If 0xFF0x00 byte sequence is found, it is just 0xFF, i.e. 0x00 is ignored. +// So if we want 0xFF, we need to append 0x00 byte +template <> +const std::array<rawspeed::uchar8, 8> Pattern<BitPumpJPEG, SaturatedTag>::Data{ + {rawspeed::uchar8(~0U), 0, rawspeed::uchar8(~0U), 0, rawspeed::uchar8(~0U), + 0, rawspeed::uchar8(~0U), 0}}; + +INSTANTIATE_TYPED_TEST_CASE_P(JPEG, BitPumpTest, Patterns<BitPumpJPEG>); + +TEST(BitPumpJPEGTest, 0xFF0x00Is0xFFTest) { + // If 0xFF0x00 byte sequence is found, it is just 0xFF, i.e. 0x00 is ignored. + static const std::array<rawspeed::uchar8, 2 + 4> data{ + {0xFF, 0x00, 0b10100100, 0b01000010, 0b00001000, 0b00011111}}; + + const Buffer b(data.data(), data.size()); + + for (auto e : {Endianness::little, Endianness::big}) { + const DataBuffer db(b, e); + const ByteStream bs(db); + + BitPumpJPEG p(bs); + + ASSERT_EQ(p.getBits(8), 0xFF); + + for (int len = 1; len <= 7; len++) + ASSERT_EQ(p.getBits(len), 1) << " Where len: " << len; + } +} + +TEST(BitPumpJPEGTest, 0xFF0xXXIsTheEndTest) { + // If 0xFF0xXX byte sequence is found, where XX != 0, then it is the end. + for (rawspeed::uchar8 end = 0x01; end < 0xFF; end++) { + static const std::array<rawspeed::uchar8, 2 + 4> data{ + {0xFF, end, 0xFF, 0xFF, 0xFF, 0xFF}}; + + const Buffer b(data.data(), data.size()); + + for (auto e : {Endianness::little, Endianness::big}) { + const DataBuffer db(b, e); + const ByteStream bs(db); + + BitPumpJPEG p(bs); + + for (int cnt = 0; cnt <= 64 + 32 - 1; cnt++) + ASSERT_EQ(p.getBits(1), 0); + } + } +} + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/BitPumpLSBTest.cpp b/src/external/rawspeed/test/librawspeed/io/BitPumpLSBTest.cpp new file mode 100644 index 000000000..703146147 --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/io/BitPumpLSBTest.cpp @@ -0,0 +1,54 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "io/BitPumpLSB.h" // for BitPumpLSB +#include "common/Common.h" // for uchar8, uint32 +#include "io/BitPumpTest.h" // for Pattern, (anonymous), GenOnesLE, BitPump... +#include <array> // for array +#include <gtest/gtest.h> // for INSTANTIATE_TYPED_TEST_CASE_P, Types + +using rawspeed::BitPumpLSB; + +namespace rawspeed_test { + +struct InvOnesTag; +struct OnesTag; + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpLSB, OnesTag>::Data = { + {/* [Byte0 Byte1 Byte2 Byte3] */ + /* Byte: [Bit7 .. Bit0] */ + 0b01001011, 0b10000100, 0b00100000, 0b11110000}}; +template <> rawspeed::uint32 Pattern<BitPumpLSB, OnesTag>::data(int index) { + const auto set = GenOnesLE(0, -1); + return set[index]; +} + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpLSB, InvOnesTag>::Data = { + {0b00100101, 0b01000010, 0b00010000, 0b11111000}}; +template <> rawspeed::uint32 Pattern<BitPumpLSB, InvOnesTag>::data(int index) { + const auto set = GenOnesLE(1, 0); + return set[index]; +} + +INSTANTIATE_TYPED_TEST_CASE_P(LSB, BitPumpTest, Patterns<BitPumpLSB>); + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/BitPumpMSB16Test.cpp b/src/external/rawspeed/test/librawspeed/io/BitPumpMSB16Test.cpp new file mode 100644 index 000000000..18ea4e52b --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/io/BitPumpMSB16Test.cpp @@ -0,0 +1,55 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "io/BitPumpMSB16.h" // for BitPumpMSB16 +#include "common/Common.h" // for uchar8, uint32 +#include "io/BitPumpTest.h" // for Pattern, (anonymous), GenOnesBE, BitPum... +#include <array> // for array +#include <gtest/gtest.h> // for INSTANTIATE_TYPED_TEST_CASE_P, Types + +using rawspeed::BitPumpMSB16; + +namespace rawspeed_test { + +struct InvOnesTag; +struct OnesTag; + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpMSB16, OnesTag>::Data = { + {/* [Byte1 Byte0 Byte3 Byte2] */ + /* Byte: [Bit0 .. Bit7] */ + 0b01000010, 0b10100100, 0b00011111, 0b00001000}}; +template <> rawspeed::uint32 Pattern<BitPumpMSB16, OnesTag>::data(int index) { + const auto set = GenOnesBE(1, 0); + return set[index]; +} + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpMSB16, InvOnesTag>::Data = + {{0b00100001, 0b11010010, 0b00001111, 0b00000100}}; +template <> +rawspeed::uint32 Pattern<BitPumpMSB16, InvOnesTag>::data(int index) { + const auto set = GenOnesBE(0, -1); + return set[index]; +} + +INSTANTIATE_TYPED_TEST_CASE_P(MSB16, BitPumpTest, Patterns<BitPumpMSB16>); + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/BitPumpMSB32Test.cpp b/src/external/rawspeed/test/librawspeed/io/BitPumpMSB32Test.cpp new file mode 100644 index 000000000..5685c9851 --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/io/BitPumpMSB32Test.cpp @@ -0,0 +1,55 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "io/BitPumpMSB32.h" // for BitPumpMSB32 +#include "common/Common.h" // for uchar8, uint32 +#include "io/BitPumpTest.h" // for Pattern, (anonymous), GenOnesBE, BitPum... +#include <array> // for array +#include <gtest/gtest.h> // for INSTANTIATE_TYPED_TEST_CASE_P, Types + +using rawspeed::BitPumpMSB32; + +namespace rawspeed_test { + +struct InvOnesTag; +struct OnesTag; + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpMSB32, OnesTag>::Data = { + {/* [Byte3 Byte2 Byte1 Byte0] */ + /* Byte: [Bit0 .. Bit7] */ + 0b00011111, 0b00001000, 0b01000010, 0b10100100}}; +template <> rawspeed::uint32 Pattern<BitPumpMSB32, OnesTag>::data(int index) { + const auto set = GenOnesBE(1, 0); + return set[index]; +} + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpMSB32, InvOnesTag>::Data = + {{0b00001111, 0b00000100, 0b00100001, 0b11010010}}; +template <> +rawspeed::uint32 Pattern<BitPumpMSB32, InvOnesTag>::data(int index) { + const auto set = GenOnesBE(0, -1); + return set[index]; +} + +INSTANTIATE_TYPED_TEST_CASE_P(MSB32, BitPumpTest, Patterns<BitPumpMSB32>); + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/BitPumpMSBTest.cpp b/src/external/rawspeed/test/librawspeed/io/BitPumpMSBTest.cpp new file mode 100644 index 000000000..dd266470e --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/io/BitPumpMSBTest.cpp @@ -0,0 +1,54 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "io/BitPumpMSB.h" // for BitPumpMSB +#include "common/Common.h" // for uchar8, uint32 +#include "io/BitPumpTest.h" // for Pattern, (anonymous), GenOnesBE, BitPump... +#include <array> // for array +#include <gtest/gtest.h> // for INSTANTIATE_TYPED_TEST_CASE_P, Types + +using rawspeed::BitPumpMSB; + +namespace rawspeed_test { + +struct InvOnesTag; +struct OnesTag; + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpMSB, OnesTag>::Data = { + {/* [Byte0 Byte1 Byte2 Byte3] */ + /* Byte: [Bit0 .. Bit7] */ + 0b10100100, 0b01000010, 0b00001000, 0b00011111}}; +template <> rawspeed::uint32 Pattern<BitPumpMSB, OnesTag>::data(int index) { + const auto set = GenOnesBE(1, 0); + return set[index]; +} + +template <> +const std::array<rawspeed::uchar8, 4> Pattern<BitPumpMSB, InvOnesTag>::Data = { + {0b11010010, 0b00100001, 0b00000100, 0b00001111}}; +template <> rawspeed::uint32 Pattern<BitPumpMSB, InvOnesTag>::data(int index) { + const auto set = GenOnesBE(0, -1); + return set[index]; +} + +INSTANTIATE_TYPED_TEST_CASE_P(MSB, BitPumpTest, Patterns<BitPumpMSB>); + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/BitPumpTest.h b/src/external/rawspeed/test/librawspeed/io/BitPumpTest.h new file mode 100644 index 000000000..143eea31c --- /dev/null +++ b/src/external/rawspeed/test/librawspeed/io/BitPumpTest.h @@ -0,0 +1,252 @@ +/* + RawSpeed - RAW file decoder. + + Copyright (C) 2018 Roman Lebedev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "common/Common.h" // for uchar8 +#include "io/Buffer.h" // for Buffer +#include "io/ByteStream.h" // for ByteStream +#include "io/Endianness.h" // for getHostEndianness, Endianness::big, Endia... +#include <array> // for array +#include <gtest/gtest.h> // for Message, AssertionResult, ASSERT_PRED_FOR... + +using rawspeed::Buffer; +using rawspeed::ByteStream; +using rawspeed::DataBuffer; +using rawspeed::Endianness; + +namespace rawspeed_test { + +template <typename T, typename Tag> struct BitPumpPatternTest {}; + +struct TestGetBitsTag; +template <typename T> struct BitPumpPatternTest<T, TestGetBitsTag> { + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + + template <typename L> static void Test(PumpT* pump, L gen) { + for (int len = 1; len <= 7; len++) + ASSERT_EQ(pump->getBits(len), gen(len)) << " Where len: " << len; + } +}; + +struct TestGetBitsNoFillTag; +template <typename T> struct BitPumpPatternTest<T, TestGetBitsNoFillTag> { + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + + template <typename L> static void Test(PumpT* pump, L gen) { + pump->fill(32); // Actually fills 32 bits + for (int len = 1; len <= 7; len++) + ASSERT_EQ(pump->getBitsNoFill(len), gen(len)) + << " Where len: " << len; + } +}; + +struct TestPeekBitsTag; +template <typename T> struct BitPumpPatternTest<T, TestPeekBitsTag> { + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + + template <typename L> static void Test(PumpT* pump, L gen) { + for (int len = 1; len <= 7; len++) { + ASSERT_EQ(pump->peekBits(len), gen(len)) << " Where len: " << len; + pump->skipBits(len); + } + } +}; + +struct TestPeekBitsNoFillTag; +template <typename T> struct BitPumpPatternTest<T, TestPeekBitsNoFillTag> { + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + + template <typename L> static void Test(PumpT* pump, L gen) { + pump->fill(32); // Actually fills 32 bits + for (int len = 1; len <= 7; len++) { + ASSERT_EQ(pump->peekBitsNoFill(len), gen(len)) + << " Where len: " << len; + pump->skipBitsNoFill(len); + } + } +}; + +struct TestIncreasingPeekLengthTag; +template <typename T> +struct BitPumpPatternTest<T, TestIncreasingPeekLengthTag> { + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + + template <typename L> static void Test(PumpT* pump, L data) { + static const auto MaxLen = 28; + for (int len = 1; len <= MaxLen; len++) + ASSERT_EQ(pump->peekBits(len), data(len)) << " Where len: " << len; + } +}; + +struct TestIncreasingPeekLengthNoFillTag; +template <typename T> +struct BitPumpPatternTest<T, TestIncreasingPeekLengthNoFillTag> { + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + + template <typename L> static void Test(PumpT* pump, L data) { + static const auto MaxLen = 28; + pump->fill(MaxLen); // Actually fills 32 bits + for (int len = 1; len <= MaxLen; len++) + ASSERT_EQ(pump->peekBitsNoFill(len), data(len)) + << " Where len: " << len; + } +}; + +template <typename T> class BitPumpTest : public ::testing::Test { +public: + using PumpT = typename T::PumpT; + using PatternT = typename T::PatternT; + +protected: + template <typename Tag, typename TestDataType, typename L> + void runTest(const TestDataType& data, L gen) { + const Buffer b(data.data(), data.size()); + + for (auto e : {Endianness::little, Endianness::big}) { + const DataBuffer db(b, e); + const ByteStream bs(db); + + PumpT pump(bs); + BitPumpPatternTest<T, Tag>::Test(&pump, gen); + } + } +}; + +TYPED_TEST_CASE_P(BitPumpTest); + +TYPED_TEST_P(BitPumpTest, GetTest) { + this->template runTest<TestGetBitsTag>(TypeParam::PatternT::Data, + TypeParam::PatternT::element); +} +TYPED_TEST_P(BitPumpTest, GetNoFillTest) { + this->template runTest<TestGetBitsNoFillTag>(TypeParam::PatternT::Data, + TypeParam::PatternT::element); +} +TYPED_TEST_P(BitPumpTest, PeekTest) { + this->template runTest<TestPeekBitsTag>(TypeParam::PatternT::Data, + TypeParam::PatternT::element); +} +TYPED_TEST_P(BitPumpTest, PeekNoFillTest) { + this->template runTest<TestPeekBitsNoFillTag>(TypeParam::PatternT::Data, + TypeParam::PatternT::element); +} +TYPED_TEST_P(BitPumpTest, IncreasingPeekLengthTest) { + this->template runTest<TestIncreasingPeekLengthTag>( + TypeParam::PatternT::Data, TypeParam::PatternT::data); +} +TYPED_TEST_P(BitPumpTest, IncreasingPeekLengthNoFillTest) { + this->template runTest<TestIncreasingPeekLengthNoFillTag>( + TypeParam::PatternT::Data, TypeParam::PatternT::data); +} + +REGISTER_TYPED_TEST_CASE_P(BitPumpTest, GetTest, GetNoFillTest, PeekTest, + PeekNoFillTest, IncreasingPeekLengthTest, + IncreasingPeekLengthNoFillTest); + +template <typename Pump, typename PatternTag> struct Pattern {}; + +struct ZerosTag; +template <typename Pump> struct Pattern<Pump, ZerosTag> { + static const std::array<rawspeed::uchar8, 4> Data; + static rawspeed::uint32 element(int index) { return 0U; } + static rawspeed::uint32 data(int len) { return 0U; } +}; +template <typename Pump> +const std::array<rawspeed::uchar8, 4> Pattern<Pump, ZerosTag>::Data{ + {/* zero-init */}}; + +struct OnesTag; +template <typename Pump> struct Pattern<Pump, OnesTag> { + static const std::array<rawspeed::uchar8, 4> Data; + static rawspeed::uint32 element(int index) { return 1U; } + static rawspeed::uint32 data(int len); +}; + +struct InvOnesTag; +template <typename Pump> struct Pattern<Pump, InvOnesTag> { + static const std::array<rawspeed::uchar8, 4> Data; + static rawspeed::uint32 element(int index) { return 1U << (index - 1U); } + static rawspeed::uint32 data(int len); +}; + +struct SaturatedTag; +template <typename Pump> struct Pattern<Pump, SaturatedTag> { + static const std::array<rawspeed::uchar8, 8> Data; + static rawspeed::uint32 element(int index) { return (1U << index) - 1U; } + static rawspeed::uint32 data(int len) { return (1U << len) - 1U; } +}; +template <typename Pump> +const std::array<rawspeed::uchar8, 8> Pattern<Pump, SaturatedTag>::Data{ + {rawspeed::uchar8(~0U), rawspeed::uchar8(~0U), rawspeed::uchar8(~0U), + rawspeed::uchar8(~0U)}}; + +auto GenOnesLE = [](int zerosToOutput, + int zerosOutputted) -> std::array<rawspeed::uint32, 29> { + std::array<rawspeed::uint32, 29> v; + rawspeed::uint32 bits = 0; + int currBit = -1; + for (auto& value : v) { + if (zerosToOutput == zerosOutputted) { + assert(currBit < 32); + bits |= 0b1 << currBit; + zerosToOutput++; + zerosOutputted = 0; + } + value = bits; + zerosOutputted++; + currBit++; + } + return v; +}; +auto GenOnesBE = [](int zerosToOutput, + int zerosOutputted) -> std::array<rawspeed::uint32, 29> { + std::array<rawspeed::uint32, 29> v; + rawspeed::uint32 bits = 0; + for (auto& value : v) { + if (zerosToOutput == zerosOutputted) { + bits |= 0b1; + zerosToOutput++; + zerosOutputted = 0; + } + value = bits; + zerosOutputted++; + bits <<= 1; + } + return v; +}; + +template <typename Pump, typename Pattern> struct PumpAndPattern { + using PumpT = Pump; + using PatternT = Pattern; +}; + +template <typename Pump> +using Patterns = + ::testing::Types<PumpAndPattern<Pump, Pattern<Pump, ZerosTag>>, + PumpAndPattern<Pump, Pattern<Pump, OnesTag>>, + PumpAndPattern<Pump, Pattern<Pump, InvOnesTag>>, + PumpAndPattern<Pump, Pattern<Pump, SaturatedTag>>>; + +} // namespace rawspeed_test diff --git a/src/external/rawspeed/test/librawspeed/io/CMakeLists.txt b/src/external/rawspeed/test/librawspeed/io/CMakeLists.txt index cc6ccfea9..480ddc4ec 100644 --- a/src/external/rawspeed/test/librawspeed/io/CMakeLists.txt +++ b/src/external/rawspeed/test/librawspeed/io/CMakeLists.txt @@ -1,4 +1,9 @@ FILE(GLOB RAWSPEED_TEST_SOURCES + "BitPumpJPEGTest.cpp" + "BitPumpLSBTest.cpp" + "BitPumpMSB16Test.cpp" + "BitPumpMSB32Test.cpp" + "BitPumpMSBTest.cpp" "EndiannessTest.cpp" ) diff --git a/src/external/rawspeed/test/librawspeed/io/EndiannessTest.cpp b/src/external/rawspeed/test/librawspeed/io/EndiannessTest.cpp index 94302e1d9..affb956f3 100644 --- a/src/external/rawspeed/test/librawspeed/io/EndiannessTest.cpp +++ b/src/external/rawspeed/test/librawspeed/io/EndiannessTest.cpp @@ -111,10 +111,10 @@ protected: AbstractGetByteSwappedTest() = default; virtual void SetUp() { auto p = this->GetParam(); - auto v = std::tr1::get<0>(p); + auto v = std::get<0>(p); // swap them around? the test is symmetrical - if (std::tr1::get<1>(p)) { + if (std::get<1>(p)) { memcpy(&in, &(v.first), sizeof(T2)); memcpy(&expected, &(v.second), sizeof(T2)); } else { diff --git a/src/external/rawspeed/test/librawspeed/io/EndiannessTest.h b/src/external/rawspeed/test/librawspeed/io/EndiannessTest.h index 9a47ba949..441f6d96a 100644 --- a/src/external/rawspeed/test/librawspeed/io/EndiannessTest.h +++ b/src/external/rawspeed/test/librawspeed/io/EndiannessTest.h @@ -35,7 +35,7 @@ template <typename T> struct intPair { }; using ushort16Type = intPair<ushort16>; -using ushort16TType = std::tr1::tuple<ushort16Type, bool>; +using ushort16TType = std::tuple<ushort16Type, bool>; static const ushort16Type ushort16Values[] = { {0x01cd, 0xcd01}, {0x024e, 0x4e02}, {0x0726, 0x2607}, {0x07e3, 0xe307}, {0x0857, 0x5708}, {0x0a0c, 0x0c0a}, {0x0a3c, 0x3c0a}, {0x0a5a, 0x5a0a}, @@ -104,7 +104,7 @@ static const ushort16Type ushort16Values[] = { }; using uint32Type = intPair<uint32>; -using uint32TType = std::tr1::tuple<uint32Type, bool>; +using uint32TType = std::tuple<uint32Type, bool>; static const uint32Type uint32Values[] = { {0x017c2230, 0x30227c01}, {0x03b26f3a, 0x3a6fb203}, {0x03e67a66, 0x667ae603}, {0x073bac8d, 0x8dac3b07}, @@ -237,7 +237,7 @@ static const uint32Type uint32Values[] = { }; using uint64Type = intPair<uint64>; -using uint64TType = std::tr1::tuple<uint64Type, bool>; +using uint64TType = std::tuple<uint64Type, bool>; static const uint64Type uint64Values[] = { {0x01a4f185910d9936, 0x36990d9185f1a401}, {0x030d4fdc9f4011b5, 0xb511409fdc4f0d03}, diff --git a/src/external/rawspeed/test/librawspeed/metadata/BlackAreaTest.cpp b/src/external/rawspeed/test/librawspeed/metadata/BlackAreaTest.cpp index 3b5be0df2..31fa2d4f0 100644 --- a/src/external/rawspeed/test/librawspeed/metadata/BlackAreaTest.cpp +++ b/src/external/rawspeed/test/librawspeed/metadata/BlackAreaTest.cpp @@ -29,13 +29,13 @@ using std::unique_ptr; namespace rawspeed_test { class BlackAreaTest - : public ::testing::TestWithParam<std::tr1::tuple<int, int, bool>> { + : public ::testing::TestWithParam<std::tuple<int, int, bool>> { protected: BlackAreaTest() = default; virtual void SetUp() override { - offset = std::tr1::get<0>(GetParam()); - size = std::tr1::get<1>(GetParam()); - isVertical = std::tr1::get<2>(GetParam()); + offset = std::get<0>(GetParam()); + size = std::get<1>(GetParam()); + isVertical = std::get<2>(GetParam()); } void checkHelper(const BlackArea& a) { diff --git a/src/external/rawspeed/test/librawspeed/metadata/CameraSensorInfoTest.cpp b/src/external/rawspeed/test/librawspeed/metadata/CameraSensorInfoTest.cpp index 2a7de669f..d6687f528 100644 --- a/src/external/rawspeed/test/librawspeed/metadata/CameraSensorInfoTest.cpp +++ b/src/external/rawspeed/test/librawspeed/metadata/CameraSensorInfoTest.cpp @@ -37,7 +37,7 @@ namespace rawspeed_test { std::vector<int> ISOList(6); class CameraSensorInfoTestDumb - : public ::testing::TestWithParam<std::tr1::tuple<int, int>> { + : public ::testing::TestWithParam<std::tuple<int, int>> { protected: CameraSensorInfoTestDumb() : mBlackLevel(std::rand()), // NOLINT do not need crypto-level randomness @@ -49,8 +49,8 @@ protected: std::rand() // NOLINT do not need crypto-level randomness }) {} virtual void SetUp() override { - mMinIso = std::tr1::get<0>(GetParam()); - mMaxIso = std::tr1::get<1>(GetParam()); + mMinIso = std::get<0>(GetParam()); + mMaxIso = std::get<1>(GetParam()); } void checkHelper(const CameraSensorInfo& csi) { diff --git a/src/external/rawspeed/test/librawspeed/metadata/CameraTest.cpp b/src/external/rawspeed/test/librawspeed/metadata/CameraTest.cpp index 1a9adfaed..963b4cecb 100644 --- a/src/external/rawspeed/test/librawspeed/metadata/CameraTest.cpp +++ b/src/external/rawspeed/test/librawspeed/metadata/CameraTest.cpp @@ -136,9 +136,9 @@ TEST(BoolHintTest, HintsBoolTrue) { ASSERT_TRUE(hints.get(key, false)); } -class BoolHintTest : public ::testing::TestWithParam<std::tr1::tuple<string>> { +class BoolHintTest : public ::testing::TestWithParam<std::tuple<string>> { protected: - virtual void SetUp() override { notTrue = std::tr1::get<0>(GetParam()); } + virtual void SetUp() override { notTrue = std::get<0>(GetParam()); } string notTrue; }; INSTANTIATE_TEST_CASE_P(NotTrue, BoolHintTest, diff --git a/src/external/rawspeed/test/librawspeed/metadata/ColorFilterArrayTest.cpp b/src/external/rawspeed/test/librawspeed/metadata/ColorFilterArrayTest.cpp index abf28a273..376c26071 100644 --- a/src/external/rawspeed/test/librawspeed/metadata/ColorFilterArrayTest.cpp +++ b/src/external/rawspeed/test/librawspeed/metadata/ColorFilterArrayTest.cpp @@ -49,7 +49,7 @@ namespace rawspeed { namespace rawspeed_test { -using Bayer2x2 = std::tr1::tuple<CFAColor, CFAColor, CFAColor, CFAColor>; +using Bayer2x2 = std::tuple<CFAColor, CFAColor, CFAColor, CFAColor>; static const iPoint2D square(2, 2); @@ -165,15 +165,15 @@ INSTANTIATE_TEST_CASE_P(CYGM, ColorFilterArrayTest, Bayer_CYGM)); static void setHelper(ColorFilterArray* cfa, Bayer2x2 param) { - cfa->setCFA(square, std::tr1::get<0>(param), std::tr1::get<1>(param), - std::tr1::get<2>(param), std::tr1::get<3>(param)); + cfa->setCFA(square, std::get<0>(param), std::get<1>(param), + std::get<2>(param), std::get<3>(param)); } static void check(ColorFilterArray* cfa, Bayer2x2 param) { - ASSERT_EQ(cfa->getColorAt(0, 0), std::tr1::get<0>(param)); - ASSERT_EQ(cfa->getColorAt(1, 0), std::tr1::get<1>(param)); - ASSERT_EQ(cfa->getColorAt(0, 1), std::tr1::get<2>(param)); - ASSERT_EQ(cfa->getColorAt(1, 1), std::tr1::get<3>(param)); + ASSERT_EQ(cfa->getColorAt(0, 0), std::get<0>(param)); + ASSERT_EQ(cfa->getColorAt(1, 0), std::get<1>(param)); + ASSERT_EQ(cfa->getColorAt(0, 1), std::get<2>(param)); + ASSERT_EQ(cfa->getColorAt(1, 1), std::get<3>(param)); } TEST_P(ColorFilterArrayTest, Constructor) { @@ -208,10 +208,10 @@ TEST_P(ColorFilterArrayTest, AssignmentConstructor) { TEST_P(ColorFilterArrayTest, SetColorAt) { ASSERT_NO_THROW({ ColorFilterArray cfa({2, 2}); - cfa.setColorAt({0, 0}, std::tr1::get<0>(param)); - cfa.setColorAt({1, 0}, std::tr1::get<1>(param)); - cfa.setColorAt({0, 1}, std::tr1::get<2>(param)); - cfa.setColorAt({1, 1}, std::tr1::get<3>(param)); + cfa.setColorAt({0, 0}, std::get<0>(param)); + cfa.setColorAt({1, 0}, std::get<1>(param)); + cfa.setColorAt({0, 1}, std::get<2>(param)); + cfa.setColorAt({1, 1}, std::get<3>(param)); check(&cfa, param); }); } @@ -237,15 +237,15 @@ TEST_P(ColorFilterArrayTest, AsString) { class ColorFilterArrayShiftTest : public ::testing::TestWithParam< - std::tr1::tuple<CFAColor, CFAColor, CFAColor, CFAColor, int, int>> { + std::tuple<CFAColor, CFAColor, CFAColor, CFAColor, int, int>> { protected: ColorFilterArrayShiftTest() = default; virtual void SetUp() { auto param = GetParam(); - mat = std::make_tuple(std::tr1::get<0>(param), std::tr1::get<1>(param), - std::tr1::get<2>(param), std::tr1::get<3>(param)); - x = std::tr1::get<4>(param); - y = std::tr1::get<5>(param); + mat = std::make_tuple(std::get<0>(param), std::get<1>(param), + std::get<2>(param), std::get<3>(param)); + x = std::get<4>(param); + y = std::get<5>(param); } Bayer2x2 mat; diff --git a/src/external/rawspeed/test/librawspeed/test/ExceptionsTest.cpp b/src/external/rawspeed/test/librawspeed/test/ExceptionsTest.cpp index 645680eaf..a8bdb9b59 100644 --- a/src/external/rawspeed/test/librawspeed/test/ExceptionsTest.cpp +++ b/src/external/rawspeed/test/librawspeed/test/ExceptionsTest.cpp @@ -33,7 +33,6 @@ #include <memory> // for unique_ptr #include <stdexcept> // for runtime_error #include <string> // for string -// IWYU pragma: no_include <bits/exception.h> using rawspeed::CameraMetadataException; using rawspeed::CiffParserException; diff --git a/src/external/rawspeed/test/librawspeed/test/RawSpeed.cpp b/src/external/rawspeed/test/librawspeed/test/RawSpeed.cpp index e743a58fa..018764f6f 100644 --- a/src/external/rawspeed/test/librawspeed/test/RawSpeed.cpp +++ b/src/external/rawspeed/test/librawspeed/test/RawSpeed.cpp @@ -18,19 +18,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "rawspeedconfig.h" #include "common/Common.h" // IWYU pragma: keep -#ifdef _OPENMP +#ifdef HAVE_OPENMP #include <omp.h> #endif // define this function, it is only declared in rawspeed: -#ifdef _OPENMP -extern "C" int rawspeed_get_number_of_processor_cores() { - return omp_get_num_procs(); +#ifdef HAVE_OPENMP +extern "C" int __attribute__((visibility("default"))) +rawspeed_get_number_of_processor_cores() { + return omp_get_max_threads(); } #else -extern "C" int __attribute__((const)) rawspeed_get_number_of_processor_cores() { +extern "C" int __attribute__((const, visibility("default"))) +rawspeed_get_number_of_processor_cores() { return 1; } #endif |