summaryrefslogtreecommitdiff
path: root/src/external/rawspeed/test
diff options
context:
space:
mode:
authorDavid Bremner <bremner@debian.org>2018-12-25 22:44:44 +0900
committerDavid Bremner <bremner@debian.org>2018-12-25 22:44:44 +0900
commit33cc53ba511843ac9857470e74e043013d3620fe (patch)
treeebc0e94b5486710fc2f381d92fab9a594f1dc62c /src/external/rawspeed/test
parent1fddb41abdd4ca3be5bfdfe019e126b188879e15 (diff)
Importing darktable_2.6.0.orig.tar.xz
Diffstat (limited to 'src/external/rawspeed/test')
-rw-r--r--src/external/rawspeed/test/librawspeed/CMakeLists.txt5
-rw-r--r--src/external/rawspeed/test/librawspeed/common/CMakeLists.txt1
-rw-r--r--src/external/rawspeed/test/librawspeed/common/ChecksumFileTest.cpp79
-rw-r--r--src/external/rawspeed/test/librawspeed/common/CommonTest.cpp128
-rw-r--r--src/external/rawspeed/test/librawspeed/common/PointTest.cpp37
-rw-r--r--src/external/rawspeed/test/librawspeed/common/RangeTest.h6
-rw-r--r--src/external/rawspeed/test/librawspeed/common/SplineTest.cpp17
-rw-r--r--src/external/rawspeed/test/librawspeed/common/ThreadingTest.cpp10
-rw-r--r--src/external/rawspeed/test/librawspeed/decompressors/AbstractHuffmanTableTest.cpp655
-rw-r--r--src/external/rawspeed/test/librawspeed/decompressors/BinaryHuffmanTreeTest.cpp243
-rw-r--r--src/external/rawspeed/test/librawspeed/decompressors/CMakeLists.txt9
-rw-r--r--src/external/rawspeed/test/librawspeed/decompressors/HuffmanTableTest.cpp133
-rw-r--r--src/external/rawspeed/test/librawspeed/io/BitPumpJPEGTest.cpp110
-rw-r--r--src/external/rawspeed/test/librawspeed/io/BitPumpLSBTest.cpp54
-rw-r--r--src/external/rawspeed/test/librawspeed/io/BitPumpMSB16Test.cpp55
-rw-r--r--src/external/rawspeed/test/librawspeed/io/BitPumpMSB32Test.cpp55
-rw-r--r--src/external/rawspeed/test/librawspeed/io/BitPumpMSBTest.cpp54
-rw-r--r--src/external/rawspeed/test/librawspeed/io/BitPumpTest.h252
-rw-r--r--src/external/rawspeed/test/librawspeed/io/CMakeLists.txt5
-rw-r--r--src/external/rawspeed/test/librawspeed/io/EndiannessTest.cpp4
-rw-r--r--src/external/rawspeed/test/librawspeed/io/EndiannessTest.h6
-rw-r--r--src/external/rawspeed/test/librawspeed/metadata/BlackAreaTest.cpp8
-rw-r--r--src/external/rawspeed/test/librawspeed/metadata/CameraSensorInfoTest.cpp6
-rw-r--r--src/external/rawspeed/test/librawspeed/metadata/CameraTest.cpp4
-rw-r--r--src/external/rawspeed/test/librawspeed/metadata/ColorFilterArrayTest.cpp32
-rw-r--r--src/external/rawspeed/test/librawspeed/test/ExceptionsTest.cpp1
-rw-r--r--src/external/rawspeed/test/librawspeed/test/RawSpeed.cpp13
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