summaryrefslogtreecommitdiff
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
parent1fddb41abdd4ca3be5bfdfe019e126b188879e15 (diff)
Importing darktable_2.6.0.orig.tar.xz
-rw-r--r--CMakeLists.txt2
-rw-r--r--RELEASE_NOTES.md4
-rw-r--r--doc/usermanual/darkroom/concepts/images/feathering_1.pngbin899473 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/concepts/images/feathering_2.pngbin240878 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/concepts/images/feathering_3.pngbin224576 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/concepts/images/feathering_4.pngbin859081 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/concepts/images/mask_refinement.pngbin6461 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/concepts/mask_refinement.xml193
-rw-r--r--doc/usermanual/darkroom/images/panel_duplicate.pngbin51877 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/modules/correction/retouch.xml266
-rw-r--r--doc/usermanual/darkroom/modules/images/denoise_profiled_ex1.pngbin21563 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/modules/images/filmic.pngbin38487 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/modules/images/retouch.pngbin16692 -> 0 bytes
-rw-r--r--doc/usermanual/darkroom/modules/tone/filmic.xml423
-rw-r--r--doc/usermanual/darkroom/panels/duplicate.xml42
-rw-r--r--doc/usermanual/images/contextual_help.pngbin347 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_auto_levels.pngbin209 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_blur.pngbin395 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_clone.pngbin684 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_cut.pngbin622 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_display_scale.pngbin335 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_fill.pngbin243 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_heal.pngbin343 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_mask.pngbin285 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_paste.pngbin294 -> 0 bytes
-rw-r--r--doc/usermanual/images/darkroom_module_retouch_switch.pngbin496 -> 0 bytes
-rw-r--r--po/fr.po2
-rw-r--r--po/hu.po2
-rw-r--r--po/nl.po24
-rw-r--r--po/ru.po8
-rw-r--r--po/sl.po62
-rw-r--r--src/external/rawspeed/.ci/Dockerfile18
-rwxr-xr-xsrc/external/rawspeed/.ci/ci-script.sh2
-rw-r--r--src/external/rawspeed/.clang-tidy14
-rw-r--r--src/external/rawspeed/.mailmap2
-rw-r--r--src/external/rawspeed/.travis.yml41
-rw-r--r--src/external/rawspeed/CMakeLists.txt50
-rw-r--r--src/external/rawspeed/README.rst4
-rw-r--r--src/external/rawspeed/bench/librawspeed/CMakeLists.txt6
-rw-r--r--src/external/rawspeed/bench/librawspeed/bench/Common.cpp3
-rw-r--r--src/external/rawspeed/bench/librawspeed/common/CMakeLists.txt7
-rw-r--r--src/external/rawspeed/bench/librawspeed/common/DefaultInitAllocatorAdaptorBenchmark.cpp79
-rw-r--r--src/external/rawspeed/bench/librawspeed/decompressors/DeflateDecompressorBenchmark.cpp7
-rw-r--r--src/external/rawspeed/bench/librawspeed/interpolators/Cr2sRawInterpolatorBenchmark.cpp2
-rw-r--r--src/external/rawspeed/bench/librawspeed/io/BitStreamBenchmark.cpp6
-rw-r--r--src/external/rawspeed/bench/librawspeed/metadata/CMakeLists.txt11
-rw-r--r--src/external/rawspeed/bench/librawspeed/metadata/CameraMetaDataBenchmark.cpp58
-rw-r--r--src/external/rawspeed/cmake/Modules/CheckZLIB.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMAr.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMCXXFilt.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMClangTidy.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMCov.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMLLD.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMNm.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMObjCopy.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMObjDump.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMProfData.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/FindLLVMRanLib.cmake2
-rw-r--r--src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake10
-rw-r--r--src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake.in17
-rw-r--r--src/external/rawspeed/cmake/Modules/GoogleTest.cmake10
-rw-r--r--src/external/rawspeed/cmake/Modules/GoogleTest.cmake.in15
-rw-r--r--src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake71
-rw-r--r--src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake.in52
-rw-r--r--src/external/rawspeed/cmake/Modules/Pugixml.cmake10
-rw-r--r--src/external/rawspeed/cmake/Modules/Pugixml.cmake.in15
-rw-r--r--src/external/rawspeed/cmake/Modules/Zlib.cmake14
-rw-r--r--src/external/rawspeed/cmake/Modules/Zlib.cmake.in11
-rw-r--r--src/external/rawspeed/cmake/OpenMP.cmake23
-rw-r--r--src/external/rawspeed/cmake/compiler-flags.cmake13
-rw-r--r--src/external/rawspeed/cmake/compiler-versions.cmake29
-rw-r--r--src/external/rawspeed/cmake/debug-info.cmake9
-rw-r--r--src/external/rawspeed/cmake/gcc-gcov.cmake2
-rw-r--r--src/external/rawspeed/cmake/iwyu.imp7
-rw-r--r--src/external/rawspeed/cmake/llvm-cov.cmake2
-rw-r--r--src/external/rawspeed/cmake/llvm-profdata.cmake2
-rw-r--r--src/external/rawspeed/cmake/sample-based-testing.cmake51
-rw-r--r--src/external/rawspeed/cmake/src-dependencies.cmake68
-rw-r--r--src/external/rawspeed/data/README.md9
-rw-r--r--src/external/rawspeed/data/cameras.xml999
-rw-r--r--src/external/rawspeed/data/cameras.xsd8
-rw-r--r--src/external/rawspeed/fuzz/CMakeLists.txt4
-rw-r--r--src/external/rawspeed/fuzz/all-fuzzers.txt73
-rw-r--r--src/external/rawspeed/fuzz/libFuzzer_dummy_main.cpp6
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decoders/TiffDecoders/main.cpp2
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/CMakeLists.txt3
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/Cr2Decompressor.cpp23
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/CMakeLists.txt58
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Common.h39
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Dual.cpp137
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Solo.cpp (renamed from src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/main.cpp)57
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/KodakDecompressor.cpp3
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/NikonDecompressor.cpp4
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressor.cpp4
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressorV5.cpp56
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/PhaseOneDecompressor.cpp66
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/decompressors/VC5Decompressor.cpp62
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/fuzz/Common.cpp11
-rw-r--r--src/external/rawspeed/fuzz/librawspeed/fuzz/Common.h5
-rw-r--r--src/external/rawspeed/src/CMakeLists.txt6
-rw-r--r--src/external/rawspeed/src/config.h.in2
-rw-r--r--src/external/rawspeed/src/external/CMakeLists.txt12
-rw-r--r--src/external/rawspeed/src/external/gopro/vc5/table17.inc291
-rw-r--r--src/external/rawspeed/src/librawspeed/common/Array2DRef.h87
-rw-r--r--src/external/rawspeed/src/librawspeed/common/CMakeLists.txt6
-rw-r--r--src/external/rawspeed/src/librawspeed/common/ChecksumFile.cpp94
-rw-r--r--src/external/rawspeed/src/librawspeed/common/ChecksumFile.h41
-rw-r--r--src/external/rawspeed/src/librawspeed/common/Common.h62
-rw-r--r--src/external/rawspeed/src/librawspeed/common/DefaultInitAllocatorAdaptor.h101
-rw-r--r--src/external/rawspeed/src/librawspeed/common/DngOpcodes.cpp15
-rw-r--r--src/external/rawspeed/src/librawspeed/common/ErrorLog.cpp2
-rw-r--r--src/external/rawspeed/src/librawspeed/common/Optional.h52
-rw-r--r--src/external/rawspeed/src/librawspeed/common/RawImage.cpp21
-rw-r--r--src/external/rawspeed/src/librawspeed/common/RawImage.h6
-rw-r--r--src/external/rawspeed/src/librawspeed/common/RawImageDataFloat.cpp19
-rw-r--r--src/external/rawspeed/src/librawspeed/common/RawImageDataU16.cpp6
-rw-r--r--src/external/rawspeed/src/librawspeed/common/RawspeedException.h9
-rw-r--r--src/external/rawspeed/src/librawspeed/common/SimpleLUT.h67
-rw-r--r--src/external/rawspeed/src/librawspeed/common/Spline.h7
-rw-r--r--src/external/rawspeed/src/librawspeed/common/TableLookUp.cpp5
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/AbstractTiffDecoder.h4
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.cpp37
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.cpp35
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/CrwDecoder.cpp28
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.cpp28
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/DcsDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/DngDecoder.cpp53
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/ErfDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.cpp93
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.h24
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.cpp18
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/MefDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/MosDecoder.cpp4
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.cpp18
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/NefDecoder.cpp32
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/NefDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.cpp114
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.h9
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/PefDecoder.cpp12
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/PefDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/RafDecoder.cpp13
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/RafDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/RawDecoder.cpp20
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.cpp48
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.h9
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/SimpleTiffDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.cpp8
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.cpp8
-rw-r--r--src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.cpp22
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.h1
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/AbstractHuffmanTable.h247
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp21
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.h19
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/AbstractParallelizedDecompressor.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/BinaryHuffmanTree.h237
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/CMakeLists.txt12
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.cpp15
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.h7
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.cpp48
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.h4
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.cpp16
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.h13
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.cpp148
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.h43
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.cpp8
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.h3
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HuffmanTable.h351
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLUT.h257
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLookup.h171
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableTree.h165
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableVector.h155
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.cpp15
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.h3
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.cpp26
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.h5
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.cpp107
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.h10
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.cpp434
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.h33
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.cpp49
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.h3
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.cpp292
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.h55
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.cpp255
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.h109
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.cpp28
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.h8
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.cpp152
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.h55
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.cpp11
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SamsungV1Decompressor.cpp21
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SamsungV2Decompressor.cpp14
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.cpp15
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.h3
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/SonyArw2Decompressor.cpp6
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/UncompressedDecompressor.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.cpp829
-rw-r--r--src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.h229
-rw-r--r--src/external/rawspeed/src/librawspeed/io/BitPumpJPEG.h6
-rw-r--r--src/external/rawspeed/src/librawspeed/io/BitPumpLSB.h6
-rw-r--r--src/external/rawspeed/src/librawspeed/io/BitPumpMSB.h4
-rw-r--r--src/external/rawspeed/src/librawspeed/io/BitPumpMSB32.h4
-rw-r--r--src/external/rawspeed/src/librawspeed/io/BitStream.h24
-rw-r--r--src/external/rawspeed/src/librawspeed/io/Buffer.cpp7
-rw-r--r--src/external/rawspeed/src/librawspeed/io/Buffer.h9
-rw-r--r--src/external/rawspeed/src/librawspeed/io/ByteStream.h8
-rw-r--r--src/external/rawspeed/src/librawspeed/io/Endianness.h25
-rw-r--r--src/external/rawspeed/src/librawspeed/io/FileIOException.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/io/FileReader.cpp11
-rw-r--r--src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.cpp2
-rw-r--r--src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.h11
-rw-r--r--src/external/rawspeed/src/librawspeed/metadata/CameraSensorInfo.cpp4
-rw-r--r--src/external/rawspeed/src/librawspeed/metadata/ColorFilterArray.cpp8
-rw-r--r--src/external/rawspeed/src/librawspeed/parsers/CiffParser.cpp15
-rw-r--r--src/external/rawspeed/src/librawspeed/parsers/FiffParser.cpp18
-rw-r--r--src/external/rawspeed/src/librawspeed/parsers/TiffParser.cpp11
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/CiffEntry.cpp10
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/CiffEntry.h5
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/CiffIFD.cpp22
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/CiffIFD.h3
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/TiffEntry.cpp11
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/TiffEntry.h2
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/TiffIFD.cpp16
-rw-r--r--src/external/rawspeed/src/librawspeed/tiff/TiffTag.h4
-rw-r--r--src/external/rawspeed/src/utilities/CMakeLists.txt4
-rw-r--r--src/external/rawspeed/src/utilities/identify/CMakeLists.txt4
-rw-r--r--src/external/rawspeed/src/utilities/identify/rawspeed-identify.cpp22
-rw-r--r--src/external/rawspeed/src/utilities/rsbench/CMakeLists.txt4
-rw-r--r--src/external/rawspeed/src/utilities/rsbench/main.cpp77
-rw-r--r--src/external/rawspeed/src/utilities/rstest/CMakeLists.txt10
-rw-r--r--src/external/rawspeed/src/utilities/rstest/MD5Benchmark.cpp2
-rw-r--r--src/external/rawspeed/src/utilities/rstest/md5.cpp34
-rw-r--r--src/external/rawspeed/src/utilities/rstest/rstest.cpp37
-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
-rw-r--r--src/iop/ashift.c5
-rw-r--r--src/libs/collect.c11
-rw-r--r--src/libs/navigation.c8
-rw-r--r--src/version_gen.c8
272 files changed, 9065 insertions, 3101 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5d515fec4..d16702804 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -221,7 +221,7 @@ else(DEFINED PROJECT_VERSION)
else(NOT SOURCE_PACKAGE)
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/src/version_gen.c)
# should be expanded by git archive due to export-subst in .gitattributes
- set(PROJECT_VERSION "archive-ea14702cd2d866d29b6270d94d04127681cf2323")
+ set(PROJECT_VERSION "archive-81883f9240ad9233d36ce2019eff558333fc15b7")
# but was it expanded?
if(PROJECT_VERSION MATCHES Format)
set(PROJECT_VERSION "unknown-version")
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index c91a5ea4a..6f25ff99d 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -95,7 +95,7 @@ when updating from the currently stable 2.4.x series, please bear in mind that y
## Camera support, compared to 2.4.0
-### Noise Profiles
+### Base Support
- Canon EOS 1500D
- Canon EOS 2000D
@@ -235,7 +235,7 @@ when updating from the currently stable 2.4.x series, please bear in mind that y
- Sony DSC-RX10M3
- Sony ILCE-7M3
-## Updated translations
+## Translations
- Afrikaans
- Albanian
diff --git a/doc/usermanual/darkroom/concepts/images/feathering_1.png b/doc/usermanual/darkroom/concepts/images/feathering_1.png
deleted file mode 100644
index db679acaf..000000000
--- a/doc/usermanual/darkroom/concepts/images/feathering_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/concepts/images/feathering_2.png b/doc/usermanual/darkroom/concepts/images/feathering_2.png
deleted file mode 100644
index c6c43414f..000000000
--- a/doc/usermanual/darkroom/concepts/images/feathering_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/concepts/images/feathering_3.png b/doc/usermanual/darkroom/concepts/images/feathering_3.png
deleted file mode 100644
index 7901edaa6..000000000
--- a/doc/usermanual/darkroom/concepts/images/feathering_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/concepts/images/feathering_4.png b/doc/usermanual/darkroom/concepts/images/feathering_4.png
deleted file mode 100644
index 2c2932a03..000000000
--- a/doc/usermanual/darkroom/concepts/images/feathering_4.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/concepts/images/mask_refinement.png b/doc/usermanual/darkroom/concepts/images/mask_refinement.png
deleted file mode 100644
index 51f77edfa..000000000
--- a/doc/usermanual/darkroom/concepts/images/mask_refinement.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/concepts/mask_refinement.xml b/doc/usermanual/darkroom/concepts/mask_refinement.xml
deleted file mode 100644
index 481d1290c..000000000
--- a/doc/usermanual/darkroom/concepts/mask_refinement.xml
+++ /dev/null
@@ -1,193 +0,0 @@
-<!DOCTYPE sect3 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
- <!ENTITY % darktable_dtd SYSTEM "../../dtd/darktable.dtd">
- %darktable_dtd;
- ]>
-<sect3 id="blending_mask_refinement">
-
- <title>Mask refinement and additional controls</title>
-
- <sect4 status="final" id="blending_mask_refinement_overview">
-
- <title>Overview</title>
-
- <para>
- When a <quote>parametric masks</quote>, a <quote>drawn mask</quote> or a combination of
- both is active several additional sliders are shown that allow for a meticulous refinement
- of the mask.
- </para>
-
- </sect4>
-
- <sect4>
-
- <title>Usage</title>
-
- <informaltable frame="none">
- <tgroup cols="2" colsep="0" rowsep="0">
- <colspec colwidth="6*"/>
- <colspec colwidth="4*"/>
- <tbody>
- <row>
- <entry>
- When blending with a mask there are some additional options to deal with the final
- mask: you may feather the mask, blur the mask, adjust the mask's brightness and
- contrast, temporarily disable the mask, or display it as an overlay image. The
- latter option is particularly useful for examining the effect of the following
- controls.
- </entry>
- <entry>
- <graphic fileref="darkroom/concepts/images/mask_refinement.png" scalefit="1" width="80%" align="center" />
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- <sect5 id="blending_mask_refinement_feathering_guide">
- <title>feathering guide</title>
- <para>
- Mask feathering smoothens a drawn or parametric mask non-uniformly such that the mask's
- edges are adjusted automatically to match the edges of the image. This mask smoothing is
- guided either by the module's input image or by its output (before blending), depending
- on what is selected in the <quote>feathering guide</quote> combobox. The feathering is
- particularly sensitive to this choice for edge-modifying modules, i.e., modules for
- sharpening or blurring an image.
- </para>
- </sect5>
-
- <sect5 id="blending_mask_refinement_feathering_radius">
- <title>feathering radius</title>
- <para>
- The <quote>feathering radius</quote> slider adjusts the strength of the feathering
- effect. Feathering works best if the drawn and/or parametric mask's edges already match
- approximately some edges in the guiding image. The larger the <quote>feathering
- radius</quote> the better the feathering algorithm can align mask edges to more distant
- edges of the image. If this radius is too large, however, the feathered mask may
- overshoot. This means it cover regions that the user actually wants to exclude.
- Feathering is turned off if the feathering radius is set to&nbsp;0.
- </para>
- </sect5>
-
- <sect5 id="blending_mask_refinement_blur">
- <title>mask blur</title>
- <para>
- Blurring the mask creates a softer transition between blended and unblended parts of an
- image and avoids artifacts. The mask blur slider controls the radius of a gaussian blur
- applied to the final blend mask. The higher the radius, the stronger the
- blur&nbsp;&ndash; or set to 0 for an unblurred mask. Gaussian blur is always applied
- after feathering if both kinds of mask adjustment are activated. This order allows to
- smooth sharp edges or artefacts that may result by feathering.
- </para>
- </sect5>
-
- <sect5 id="blending_mask_refinement_mask_brightness">
- <title>mask opacity</title>
- <para>
- The strength of the module's effect is determined by the mask's local opacity.
- Feathering and blurring the mask may result in a mask with reduced opacity, which
- implies a reduced effect. Therefore, the <quote>mask opacity</quote> slider allows to
- readjust the mask opacity. If the opacity is decreased (negative slider values) least
- opaque parts are affected stronger than most opaque parts. Contrary, if the mask opacity
- is increased (positive slider values) most opaque parts are affected stronger than least
- opaque parts. As a consequence, completely opaque portions of the mask always remain
- opaque and completely transparent portions remain transparent. This is to ensure that
- regions which have been excluded from or included to a module's effect by setting the
- mask's opacity to 0% or 100% remain excluded or included even if the mask opacity is
- adjusted by this slider.
- </para>
- </sect5>
-
- <sect5 id="blending_mask_refinement_mask_contrast">
- <title>mask contrast</title>
- <para>
- This slider increases or decreases the mask contrast. This means it allows to modify the
- transition between opaque and transparent mask parts.
- </para>
- </sect5>
-
- <sect5 id="blending_mask_refinement_temp_off">
- <title>temporarily switch off mask</title>
- <para>
- Sometimes it is useful to visualize the module's effect without the mask taking action.
- You can do so by clicking on the
- <inlinegraphic fileref="&icon_module_eye;" scalefit="1" width="2%" align="center"/>
- symbol, which will temporarily deactivate the mask&nbsp;&ndash; the selected blend mode
- and opacity remain in effect. Switch this button on and off to see if the mask is acting
- on the image as intended.
- </para>
- </sect5>
-
- <sect5 id="blending_mask_refinement_display">
- <title>display mask</title>
- <para>
- Clicking on the
- <inlinegraphic fileref="&icon_module_mask;" scalefit="1" width="2%" align="center"/>
- symbol will display the current mask as a yellow overlay over a black-and-white version
- of your image. Solid yellow indicates an opacity of 100%; a fully visible gray
- background image without yellow overlay indicates an opacity of 0%.
- </para>
- </sect5>
-
- </sect4>
-
- <sect4>
-
- <title>Examples</title>
-
- <sect5 id="blending_examples_feathering">
- <title>Feathering a drawn mask</title>
- <para>
- <informaltable frame="none">
- <tgroup cols="4" colsep="0" rowsep="0">
- <colspec colwidth="1*"/>
- <colspec colwidth="1*"/>
- <colspec colwidth="1*"/>
- <colspec colwidth="1*"/>
- <tbody>
- <row>
- <entry>
- <graphic fileref="darkroom/concepts/images/feathering_1.png" scalefit="1" width="96%" align="center" />
- </entry>
- <entry>
- <graphic fileref="darkroom/concepts/images/feathering_2.png" scalefit="1" width="96%" align="center" />
- </entry>
- <entry>
- <graphic fileref="darkroom/concepts/images/feathering_3.png" scalefit="1" width="96%" align="center" />
- </entry>
- <entry>
- <graphic fileref="darkroom/concepts/images/feathering_4.png" scalefit="1" width="96%" align="center" />
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- </para>
- <para>
- It can be rather tedious to create a drawn mask by hand, which matches precisely a
- particular object or person in an image. In this example, we want to enhance the color
- contrast of the lion sculpture shown in the left image above without affecting the
- background. For this purpose, a rough selection of the sculpture is created by a drawn
- mask. See the second image above, where the <quote>displays mask</quote> feature is
- active. Note that the mask is rather fuzzy and it does not match precisely the lion
- sculpture. Adjusting the feathering radius, the mask opacity and the mask contrast leads
- to a well matching mask with little effort. In the third image above the feathering
- radius has been adjusted to 50, a blur radius of 5 was chosen to smooth the mask to some
- degree. The mask opacity and the mask contrast have been increased to 0.3 and 0.5,
- respectively, to further enhance the mask. The last image above shows the final result,
- where the color enhancement via the color contrast module (see
- <xref
- linkend="color_contrast"/>) is restricted to the lion sculpture due to the mask.
- </para>
- <para>
- Mask feathering works in this example particularly well because the sculpture in the
- original image is well separated from the blurry background. The distinct edge at the
- border of the sculpture guides the feathering mask adjustment to match the shape of the
- sculpture. Note that feathering can be applied to drawn masks as well as to parametric
- masks.
- </para>
- </sect5>
-
- </sect4>
-
-</sect3>
diff --git a/doc/usermanual/darkroom/images/panel_duplicate.png b/doc/usermanual/darkroom/images/panel_duplicate.png
deleted file mode 100644
index 8c8ccb773..000000000
--- a/doc/usermanual/darkroom/images/panel_duplicate.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/modules/correction/retouch.xml b/doc/usermanual/darkroom/modules/correction/retouch.xml
deleted file mode 100644
index 32fb23443..000000000
--- a/doc/usermanual/darkroom/modules/correction/retouch.xml
+++ /dev/null
@@ -1,266 +0,0 @@
-<!DOCTYPE sect3 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
- <!ENTITY % darktable_dtd SYSTEM "../../../dtd/darktable.dtd">
- %darktable_dtd;
- ]>
-<sect3 status="final" id="retouch">
-
- <title>Retouch</title>
-
- <indexterm>
- <primary>modules</primary>
- <secondary>retouch</secondary>
- </indexterm>
-
- <indexterm>
- <primary>retouch</primary>
- </indexterm>
-
- <sect4>
-
- <title>Overview</title>
-
- <informaltable frame="none">
- <tgroup cols="2" colsep="0" rowsep="0">
- <colspec colwidth="6*"/>
- <colspec colwidth="4*"/>
- <tbody>
- <row>
- <entry>
- Retouch allows to heal, clone, fill and blur certain areas of the image. It can
- perform a wavelet decomposition which separates the image into different frequency
- scales, from fine to coarse, and apply retouch operations to each wavelet scale
- individually.
- </entry>
- <entry>
- <graphic fileref="darkroom/modules/images/retouch.png" scalefit="1" width="80%" align="center" />
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- </sect4>
-
- <sect4>
-
- <title>Usage</title>
-
- <para>
- For a basic use, with default parameters, add the shapes to the image like with the spot
- removal module (see <xref linkend="spot_removal"/>). To use the wavelet decompose first
- select one of the scales as the current scale (see below) and then add the shapes.
- </para>
-
- <para>
- The GUI is divided in three main sections: wavelet decompose, retouch tools and shapes.
- </para>
-
- <sect5>
- <title>wavelet decompose section</title>
- <para>
- The wavelet decompose toolbar controls the wavelet decompose algorithm. It has a central
- area divided in boxes and two sliders. The first box, scale zero, represents the
- original image, the second is the wavelet scale 1, and so on.
- </para>
- <para>
- The bottom slider adjusts the number of scales, zero means no wavelet decompose is done.
- The maximum number of scales depends on the image size, but any number can be selected.
- If the image is not big enough for the selected number of scales the maximum number of
- scales for this image size is used and the rest of the scales are ignored.
- </para>
- <para>
- The image is decomposed to the selected number of scales plus the residual image, so if
- 5 is selected as the number of scales, scale zero is the original image, scales 1 to 5
- are the detail scales, and scale 6 is the residual image. As a visual aid, the original
- image is always represented by a black box, detail scales are light gray, residual image
- white and inactive scales dark gray.
- </para>
- <para>
- The central area allows to select the current scale on which the user can then apply
- retouch tools by left clicking any of the boxes. The selected scale is marked by a red
- frame. Any scale can be selected as the current scale, even if it is greater than the
- number of scales. If a shape is added to a scale greater than the residual image it will
- be ignored, as the scale is not processed.
- </para>
- <para>
- Only the shapes on the current scale are displayed, when the current scale is changed
- shapes will be displayed accordingly.
- </para>
- <para>
- A green line on top of each box indicates that the scale has shapes associated with it.
- </para>
- <para>
- Fine detail scales can only be seen at certain zoom level, a light gray line on top of
- each box will indicate that the scale is visible at current zoom level.
- </para>
- <para>
- The top slider adjusts the <emphasis>merge scale</emphasis> feature. This setting allows
- to apply a common edit on multiple consecutive scales within a group starting from the
- highest scale (not including the residual image) down to the one selected by this
- slider. If the slider is set to 3 and the maximum scale is 5 then all edits that are
- added to scale 5 will be applied to scales 3 to 5. Edits added to scale 4 will be
- applied to scales 3 and 4, and edits added to scale 3 will be applied only to scale 3.
- <emphasis>Merged scales</emphasis> are represented by a green-yellow color. A value of
- zero means that the merge feature is not used.
- </para>
- <para>
- The display wavelet scale button (
- <inlinegraphic fileref="&icon_retouch_display_scale;" scalefit="1" width="2%" align="center" />
- ) allow to view the current wavelet scale. The module's blend feature is temporary
- disabled when this option is set. If blending in the module is active and the option to
- display masks is active this option cannot be set. When this option is active a new
- section, <quote>preview single scale</quote>, will be displayed, allowing to adjust the
- levels for the displayed image. This is purely a convenience feature so you can adjust
- wavelet scale display to your needs. It does not have an effect on the final output
- image. An auto levels button (
- <inlinegraphic fileref="&icon_retouch_auto_levels;" scalefit="1" width="2%" align="center" />
- ) is also available; it works on the displayed image, so different results can be
- expected depending on the image displayed when zoomed in/out. Levels are only applied to
- detail scales, not the original or residual image.
- </para>
- <para>
- The cut and paste buttons allow to move all the shapes from one scale to another. In
- order to do this first select the current scale, click the cut button (
- <inlinegraphic fileref="&icon_retouch_cut;" scalefit="1" width="2%" align="center" />
- ), select the destination scale and click paste (
- <inlinegraphic fileref="&icon_retouch_paste;" scalefit="1" width="2%" align="center" />
- ). This can be useful when there are edits on the residual image and one has to change
- the number of scales; since the residual image is changed, shapes need to be moved to
- the new one.
- </para>
- <para>
- The switch off shapes button (
- <inlinegraphic fileref="&icon_retouch_switch;" scalefit="1" width="2%" align="center" />
- ) temporarily disables the processing of all shapes for a simple before/after
- comparison.
- </para>
- <para>
- The display masks button (
- <inlinegraphic fileref="&icon_retouch_mask;" scalefit="1" width="2%" align="center" />
- ) works similar to the one on the blend module, but it will display only the shapes on
- the current scale. This option and display mask on the blend module cannot be set at the
- same time.
- </para>
- </sect5>
-
- <sect5>
- <title>retouch tools section</title>
- <para>
- The shapes toolbar allows to add new shapes to the image. Shapes creation/editing
- behaves like in the spot removal module. In addition, by Ctrl+click on any shape button,
- the <emphasis>continuous add mode</emphasis> is activated. Once a shape is added,
- darktable will remain in creation mode, allowing to add another shape of the same type.
- To change the shape type to be added Ctrl+click on a different shape button to continue
- on continuous add mode or plain click to add a single shape. To leave the continuous add
- mode right click on any clear area of the image.
- </para>
- <para>
- The algorithms toolbar allows to select between heal (
- <inlinegraphic fileref="&icon_retouch_heal;" scalefit="1" width="2%" align="center" />
- ), clone (
- <inlinegraphic fileref="&icon_retouch_clone;" scalefit="1" width="2%" align="center" />
- ), fill (
- <inlinegraphic fileref="&icon_retouch_fill;" scalefit="1" width="2%" align="center" />
- ) and blur (
- <inlinegraphic fileref="&icon_retouch_blur;" scalefit="1" width="2%" align="center" />
- ) algorithms. Before actually creating a shape the algorithm must be
- selected&nbsp;&ndash; once a shape is created the algorithm cannot be changed.
- </para>
- <para>
- Any combination of shape type and algorithm can be added to the image.
- </para>
- </sect5>
-
- <sect5>
- <title>shapes section</title>
- <para>
- The shape selected field displays the selected shape (if any). To select a shape click
- on it, to deselect click on a free area on the image.
- </para>
- <para>
- Mask opacity is displayed when a shape is selected. It displays/sets the opacity of the
- mask. Opacity is a property of the currently selected shape and won't be used as default
- value for newly added shapes.
- </para>
- <para>
- Different properties will be displayed depending on the selected algorithm:
- <informaltable frame="none" width="80%">
- <tgroup cols="2" colsep="0" rowsep="0">
- <colspec colwidth='1*'/>
- <colspec colwidth='4*'/>
- <tbody>
- <row>
- <entry>
- <emphasis>fill algorithm</emphasis>
- </entry>
- <entry>
- <variablelist>
-
- <varlistentry>
-
- <term>fill mode</term>
-
- <listitem><para>
- Can be erase or color. Erase is used to delete details from a wavelet
- scale. Color allows to select a color to fill the area defined by the
- shape.
- </para></listitem>
-
- </varlistentry>
-
- <varlistentry>
-
- <term>brightness</term>
-
- <listitem><para>
- Adds the selected value to the color, allowing to make it brighter or
- darker. Works the same with both fill modes.
- </para></listitem>
-
- </varlistentry>
-
- </variablelist>
- </entry>
- </row>
- <row>
- <entry>
- <emphasis>blur algorithm</emphasis>
- </entry>
- <entry>
- <variablelist>
-
- <varlistentry>
-
- <term>blur type</term>
-
- <listitem><para>
- Can be gaussian or bilateral.
- </para></listitem>
-
- </varlistentry>
-
- <varlistentry>
-
- <term>blur radius</term>
-
- <listitem><para>
- Sets the blur radius.
- </para></listitem>
-
- </varlistentry>
-
- </variablelist>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- The value set on each one of these properties is used as a default when a new shape is
- created.
- </para>
- </sect5>
-
- </sect4>
-
-</sect3>
diff --git a/doc/usermanual/darkroom/modules/images/denoise_profiled_ex1.png b/doc/usermanual/darkroom/modules/images/denoise_profiled_ex1.png
deleted file mode 100644
index 1f8397779..000000000
--- a/doc/usermanual/darkroom/modules/images/denoise_profiled_ex1.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/modules/images/filmic.png b/doc/usermanual/darkroom/modules/images/filmic.png
deleted file mode 100644
index 6d11b3dad..000000000
--- a/doc/usermanual/darkroom/modules/images/filmic.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/modules/images/retouch.png b/doc/usermanual/darkroom/modules/images/retouch.png
deleted file mode 100644
index 22346219c..000000000
--- a/doc/usermanual/darkroom/modules/images/retouch.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/darkroom/modules/tone/filmic.xml b/doc/usermanual/darkroom/modules/tone/filmic.xml
deleted file mode 100644
index 984c89c42..000000000
--- a/doc/usermanual/darkroom/modules/tone/filmic.xml
+++ /dev/null
@@ -1,423 +0,0 @@
-<!DOCTYPE sect3 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
- <!ENTITY % darktable_dtd SYSTEM "../../../dtd/darktable.dtd">
- %darktable_dtd;
- ]>
-<sect3 status="final" id="filmic">
-
- <title>Filmic</title>
-
- <indexterm>
- <primary>modules</primary>
- <secondary>filmic</secondary>
- </indexterm>
-
- <indexterm>
- <primary>filmic</primary>
- </indexterm>
-
- <sect4>
-
- <title>Overview</title>
-
- <informaltable frame="none">
- <tgroup cols="2" colsep="0" rowsep="0">
- <colspec colwidth="6*"/>
- <colspec colwidth="4*"/>
- <tbody>
- <row>
- <entry>
- <para>
- This module compresses the tonal range of an image by reproducing the tone and
- color response of classic film. Doing so, it will protect the colors and the
- contrast in mid-tones, recover the shadows, and compress bright highlights. It
- is very suitable in portrait photography, especially in back-lighting
- situations, but will need extra care when details need to be preserved in
- highlights (e.g. clouds).
- </para>
-
- <para>
- The module is derived from the same named module in Blender 3D modeller by T. J.
- Sobotka. While it is primarily intended to recover high-dynamic range from raw
- sensor data, it can be used with any image in replacement of the base curve
- module. A full tutorial with examples and comments on the results can be found
- on
- <ulink url="https://eng.aurelienpierre.com/2018/11/30/filmic-darktable-and-the-quest-of-the-hdr-tone-mapping/"><emphasis>its
- developer's website</emphasis></ulink>.
- </para>
- </entry>
- <entry>
- <graphic fileref="darkroom/modules/images/filmic.png" scalefit="1" width="80%" align="center" />
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- </sect4>
-
- <sect4>
-
- <title>Prerequisites</title>
-
- <para>
- In order to get the best out of filmic, images need some preparation:
- <itemizedlist>
-
- <listitem><para>
- In-camera, expose the shot <quote>to the right</quote>. This implies under exposing
- the shot so that the highlights are at the right of the histogram, just on the verge
- of clipping, but not clipped. It does not matter if the picture preview is very dark
- on your camera screen: as long as highlights are unclipped, filmic should be able to
- recover details from the raw data. Beware that clipped data are not recoverable. Some
- cameras have a clipping alert preview to help you diagnose this, and some even have an
- highlight-priority exposure mode.
- </para></listitem>
-
- <listitem><para>
- In darktable's exposure module, correct the black level and the exposure value to
- avoid any clipping. It is especially important to avoid negative pixels values (in
- black areas), because they will be clipped in filmic. For some cameras models (Canon,
- mainly), rawspeed, the raw decoding library of darktable, may set an exaggerated black
- level, resulting in crushed blacks and negative values. If so, brighten the blacks by
- setting a negative black level value in the exposure module.
- </para></listitem>
-
- <listitem><para>
- If you plan on using filmic's auto-tuners, use the white balance module first to
- correct any color casts and get neutral colors. In RGB color spaces, luminance and
- chrominance are linked, and filmic's luminance detection relies on accurate measures
- of both. If your picture is very noisy, add an initial step of denoising to help the
- black exposure readings, and use a high quality demosaicing.
- </para></listitem>
-
- <listitem><para>
- If you plan using filmic's chrominance preservation mode, avoid using any tone mapping
- module as well as the base curve module. These may produce unpredictible color shifts
- that would make the chrominance preservation useless. Neither of these modules is
- usually needed if you use filmic.
- </para></listitem>
-
- </itemizedlist>
- </para>
-
- </sect4>
-
- <sect4>
-
- <title>Usage</title>
-
- <para>
- There are 4 steps in the filmic process:
- <itemizedlist>
-
- <listitem><para>
- Apply a logarithmic shaper to the RGB signal, to raise the midtones luminance in the
- same way human eyes and film respond to lightness. This is similar to what
- <emphasis>unbreak input profile</emphasis> does in its logarithmic mode.
- </para></listitem>
-
- <listitem><para>
- Apply an S-shaped parametric curve to enhance the contrast and remap the grey value to
- the middle grey of the display. This is similar to what the base curve or tone curve
- modules do.
- </para></listitem>
-
- <listitem><para>
- Apply a selective desaturation on extreme luminance values so that shadows degrade
- progressively toward pure black and highlights degrade progressively toward pure
- white.
- </para></listitem>
-
- <listitem><para>
- Apply an inverse gamma transfer function to linearize the output for the display
- gamma. Having a gamma correction applied on top of logarithmically encoded data would
- result in a double-up, with the luminance raised twice.
- </para></listitem>
-
- </itemizedlist>
- </para>
-
- <para>
- The sliders' ranges of filmic are limited to usual and safe values, but values are allowed
- out of these ranges by clicking on the sliders with the right button and inputting values
- on the keyboard. Filmic has no neutral parameters resulting in a no-operation: as soon as
- the module is enabled, the image is always at least slightly affected. The default
- parameters are tuned to have minimal impact on most pictures.
- </para>
-
- <sect5>
- <title>Middle-grey luminance</title>
- <para>
- The middle-grey luminance is the luminance in XYZ space of the scene referred 18% grey.
- Its color picker tool reads the average luminance over the drawn area. If you happen to
- have a grey card or a color chart (IT8 chart or colorchecker) shot in the scene lighting
- conditions, then the grey color picker tool can be used to quickely sample the luminance
- of the grey patch on the picture. In other situations, the color picker can be used to
- sample the average luminance of the subject.
- </para>
- <para>
- This setting has an effect on the picture that is analogous to a lightness correction.
- Values close to 100% will not compress the highlights but will fail to recover shadows.
- Values close to 0% will recover greatly the shadows but will compress the highlights
- more harshely and result in local-contrast losses. The standard middle-grey value for
- linearly encoded camera RGB is 18%. Good values of grey are usually the average
- luminance of the whole picture or of the subject. Values much higher than 18% will make
- the filmic S curve difficult to control. In studio and indoors (low dynamic range
- scenes), proper grey values will be found between 15-18%. In high dynamic range scenes
- (landscapes, back-lit portraits), proper grey values will lie between 1.25 and 9%.
- </para>
- <para>
- When modifying the middle-grey luminance, the white and black exposures are
- automatically slided accordingly, to preserve the dynamic range from clipping and to
- help you set find the righ parameter faster. If you are not happy with the auto
- adjustment performed by the grey slider, you can correct again the white and black
- exposure parameters afterwards.
- </para>
- </sect5>
-
- <sect5>
- <title>White relative exposure</title>
- <para>
- The white relative exposure is the number of stops (EV) between pure white and the
- middle grey. It is the right bound of the dynamic range. It should be adjusted to avoid
- highlight clipping. The white exposure color picker tool reads the maximum luminance in
- XYZ space over the drawn area, assumes it is pure white, and sets the white exposure
- parameter to remap the reading to 100% luminance.
- </para>
- <para>
- When the grey is set at 18%, the white exposure will always be around 2.45EV. When the
- grey is set at 100%, the white exposure should be set at 0EV.
- </para>
- </sect5>
-
- <sect5>
- <title>Black relative exposure</title>
- <para>
- The black relative exposure is the number of stops (EV) between pure black and the
- middle grey. It is the left bound of the dynamic range. The black exposure color-picker
- tool reads the minimum luminance in XYZ space over the drawn area, assumes it is pure
- black, and sets the black exposure parameter to remap the minimum reading to 0%
- luminance. The black color picker measurement is very sensitive to noise, and cannot
- identify if the minimum luminance is pure black (actual data) or just noise. It works
- better on low ISO pictures and with high quality demosaicing. When the color picker puts
- the black exposure at -16EV, it is a sign that the measure failed and you need to adjust
- it manually.
- </para>
- <para>
- The black relative exposure allows you to choose how far you want to recover lowlights.
- On the contrary to the white exposure it will not be possible to completely avoid
- clipping blacks. When the black exposure is very low, the filmic S curve becomes very
- difficult to control and the final contrast is often faded. Every camera sensor has a
- maximum physical dynamic range for each ISO value (you can find them measured on
- <ulink url="https://www.dxomark.com/"><emphasis>DXOmark</emphasis></ulink> or
- <ulink url="https://www.dpreview.com/"><emphasis>DPreview</emphasis></ulink>), the
- software dynamic range in filmic (dynamic range = white exposure - black exposure)
- should generally not be greater than the physical dynamic range of the sensor (10-14EV
- in most cases). For better control of the filmic S curve, the black exposure should be
- kept close to the white exposure in absolute value (and ideally greater, in absolute
- value), so the dynamic range is almost centered in 0EV. Another guide to validate the
- black exposure value is the S curve should always go through the center of the graph
- display (it will not when challenging parameter are set). Notice that the dynamic range
- of the scene car be lower than the camera's one, especially indoors.
- </para>
- </sect5>
-
- <sect5>
- <title>Safety factor and auto-tune</title>
- <para>
- The auto-tune color picker combines all three color pickers above, and will allow to set
- the grey, white and black exposures all at once, using the average of the drawn region
- as the grey estimation, the maximum as the white, and the minimum as the black. This
- gives good results in landscape photography but usually fails for portraits and indoor
- scenes.
- </para>
- <para>
- When no true white and no true black are available on the scene, the maximum and minimum
- XYZ values read on the image are not valid assumptions anymore, so the safety factor
- will allow you to shrink or enlarge symmetrically the detected dynamic range and the
- current parameters. This works with all color pickers.
- </para>
- </sect5>
-
- <sect5>
- <title>Contrast</title>
- <para>
- The filmic S curve is created from the user parameters, by computing the position of
- virtual nodes and interpolating them, similarly to the tone curve module (but here, the
- nodes cannot be moved manually). While this allow a quicker curve parametrization, not
- all the combinations of paramater deliver good curves, and the graph display will give a
- diagnostic interface. Good curves are either graceful S with a linear central portion
- and curved extremities, or lines following the diagonal of the graph.
- </para>
- <para>
- The contrast parameter drives the slope of the central part of the curve. The larger the
- dynamic range is, the greater the contrast should be set, to avoid reversed branches
- that would invert the image contrast. Proper values of contrast lie between 1.4 (at 8EV
- dynamic range) and 1.7 (at 14EV dynamic range). This parameter will mostly affect
- mid-tones.
- </para>
- </sect5>
-
- <sect5>
- <title>Latitude</title>
- <para>
- The latitude is the range between the 2 nodes enclosing the central linear portion of
- the curve. The bigger the latitude is, the more linearly the luminance is affected,
- which is desirable to preserve the chrominance. The latitude defines the range of
- luminances that is not desaturated in the third step of filmic processing. This
- parameter will mostly affect extreme luminances. It is usually better to keep it as
- large as possible, and adjust the contrast to avoid clipping. Proper values lie between
- 25% and 50% of the dynamic range, and should be increased by 1EV each time the grey
- value is divided by 2.
- </para>
- </sect5>
-
- <sect5>
- <title>Balance hightlights/shadows</title>
- <para>
- By default, the latitude is distributed toward middle-grey accordingly to the dynamic
- range: when the dynamic range in centered in 0, it means the latitude is centered in
- 50%. In real life situations, the dynamic range is often decentered, with a bigger part
- allowed to shadows, and so will be the latitude. However, this can produce clipping in
- blacks. The balance parameter allows to slide the latitude along the slope, toward the
- shadows or toward the highlights. This way, the contrast will be preserved in mid-tones,
- but more room will be allowed to one extremity of the dynamic range so clipping will be
- avoided. This should usually be used to center the latitude at 50%, on the graph
- display.
- </para>
- </sect5>
-
- <sect5>
- <title>Saturation</title>
- <para>
- The saturation parameter is a finetuning control that applies on top of the latitude
- parameter. By default, the picture is desaturated selectively in extreme luminances
- (near white and near black), and untouched in mid-tones. This is how film behaves and is
- also useful to avoid gamut clipping, because very bright and very saturated colours are
- usually out of the sRGB gamut.
- </para>
- <para>
- The desaturation mask is a gaussian window which standard deviation is latitude ×
- saturation, and which is centered on the latitude. As the latitude affects the luminance
- and the saturation, you should set it first, leaving the saturation at 100%. Once you
- are happy with the luminance mapping, you can then finetune the saturation parameter to
- adjust the desaturation.
- </para>
- <para>
- The saturation parameter sets at 100% means the desaturation window standard deviation
- is 100% of the latitude width. To desaturate more aggressively at extreme luminances,
- the saturation should be set lower than 100%. To almost disable the desaturation,
- saturation values can be set as high as 1000%, using right-click and inputting the
- values on the keyboard.
- </para>
- </sect5>
-
- <sect5>
- <title>Intent</title>
- <para>
- The intent parameter controls the interpolation algorithm used to derive the curve from
- the position of the nodes. It is similar to the tone curve module, but the options are
- translated into common language. <emphasis>Contrasted</emphasis> uses a cubic spline
- interpolation that produce a smooth round curve and pleasing contrast, however it can be
- sensible to nodes in close proximity and produce cusps and oscillations in this setup.
- <emphasis>Linear</emphasis> uses a monotonic Hermite interpolation that ensures the
- monotonicity of the curve, but produces a flatter contrast at the extremities.
- <emphasis>Faded</emphasis> uses a Catmul-Rom centripetal interpolation, designed to
- avoid cusps at all cost, but produces even flatter contrast at the extremities, which
- can be used creatively to emulate old faded photographs. <emphasis>Optimized</emphasis>
- is an average between the <emphasis>contrasted</emphasis> and
- <emphasis>linear</emphasis> modes, providing a fair trade-off at the expense of being
- heavier on the CPU.
- </para>
- </sect5>
-
- <sect5>
- <title>Preserve the chrominance</title>
- <para>
- The chrominance preservation mode is an advanced mode that cannot be used <quote>as
- is</quote> and needs extra-corrections. In regular mode, filmic applies its correction
- in ProPhotoRGB space, using the three RGB channels separately. This looks good most of
- the time, but can result in color hue shifts because no consistency between channels in
- ensured.
- </para>
- <para>
- When using the chrominance preservation mode, the RGB ratios are saved before any
- correction in filmic. Only the maximum of the thre RGB channels is used in the
- tone-mapping, as an estimation of the luminance. At the end of the process, the RGB
- ratios are restored as before. This leads to marginally faster runtimes, and links the
- thre RGB channels all along the process, to ensure the hue and the saturation are kept
- untouched, which is desirable when you performed precise color adjustments. However,
- this does not follow the eye response to luminance, so, keeping the saturation as is
- when pushing up the luminance will always look oversaturated. This is why, when using
- this mode, an extra desaturation should be performed, for example, using the output
- saturation in color balance module at 65 to 85%. In that case, color balance should be
- used to adjust the main saturation of the mid-tones, then an additional pass would fix
- the saturation of extreme luminances with the saturation parameter of filmic, set
- between 12 to 33%.
- </para>
- <para>
- It is advised to perform all filmic settings in the regular RGB mode (unlinked
- channels), then enable the chrominance preservation last, and then adjust the
- saturation.
- </para>
- </sect5>
-
- <sect5>
- <title>Black luminance</title>
- <para>
- The destination parameters set the target luminance values used to remap the tones
- through filmic. The default parameters will work 99% of the times, the remaining 1%
- being when you output in linear RGB space (REC709, REC2020) for media handling
- log-encoded data. These settings are then to be used with caution because darktable does
- not allow separate pipelines for diplay preview and for file output.
- </para>
- <para>
- The black luminance parameter allows to set the ground-level black of the target medium.
- Set it greater than 0% if you want raised, faded blacks to achieve a retro look.
- </para>
- </sect5>
-
- <sect5>
- <title>Middle-grey destination</title>
- <para>
- This is the middle-grey of the output medium, that is used as a target for the filmic S
- curve central node. On gamma corrected media, the actual grey is computed with the gamma
- correction (middle-grey^(1/gamma)), so a middle-grey parameter of 18% with a gamma of
- 2.2 gives an actual middle-grey target of 45.87%.
- </para>
- </sect5>
-
- <sect5>
- <title>White luminance</title>
- <para>
- The white luminance parameter allows to set the ceiling level white of the target
- medium. Set it lower than 100% if you want dampened, muted whites to achieve a retro
- look.
- </para>
- </sect5>
-
- <sect5>
- <title>Destination power factor</title>
- <para>
- The power of the output transfer function, often improperly called the gamma (only
- screen have a gamma), is the parameter used to raise or compress the mid-tones to
- account for the display non-linearities or to avoid quantization artifacts when encoding
- in 8 bits file formats. This is a common operation when applying ICC color profiles
- (except for linear RGB spaces, like REC 709 or REC 2020, which have a linear
- <quote>gamma</quote> of 1.0). However, at the output of filmic, the signal is
- logarithmically encoded, which is not something ICC color profiles know to handle. As a
- consequence, if we let them apply a gamma 1/2.2 on top, it will result in a double up,
- and the middle-grey will be remapped to 76% instead of 45% as it should.
- </para>
- <para>
- To avoid double ups and washed pictures, filmic applies a <quote>gamma</quote>
- compression reverting the output ICC gamma correction, so the middle-grey is correctely
- remapped at the end. To remove this compression, set the destination power factor to 1.0
- and the middle-grey destination to 45%.
- </para>
- </sect5>
-
- </sect4>
-
-</sect3>
diff --git a/doc/usermanual/darkroom/panels/duplicate.xml b/doc/usermanual/darkroom/panels/duplicate.xml
deleted file mode 100644
index 83f665c96..000000000
--- a/doc/usermanual/darkroom/panels/duplicate.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE sect2 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
- <!ENTITY % darktable_dtd SYSTEM "../../dtd/darktable.dtd">
- %darktable_dtd;
- ]>
-<sect2 status="final" id="duplicate">
-
- <title>Duplicate manager</title>
-
- <indexterm>
- <primary>darkroom panels</primary>
- <secondary>duplicate</secondary>
- </indexterm>
-
- <indexterm>
- <primary>duplicate</primary>
- </indexterm>
-
- <informaltable frame="none">
- <tgroup cols="2" colsep="0" rowsep="0">
- <colspec colwidth="6*"/>
- <colspec colwidth="4*"/>
- <tbody>
- <row>
- <entry>
- The duplicate manager lists all versions (see duplicate <xref linkend="selected_images"/>)
- of your image with their preview thumbnails.
- Single click on a thumbnail to temporarily show the related version inside the center view.
- Double click to completely switch to this version.
- Top-right buttons let you create new duplicates. Either a 'virgin' version, or an
- exact duplicate of the current image.
- For your convenience, you can also set a name to each versions.
- </entry>
- <entry>
- <graphic fileref="darkroom/images/panel_duplicate.png" scalefit="1" width="80%" align="center" />
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
-</sect2>
diff --git a/doc/usermanual/images/contextual_help.png b/doc/usermanual/images/contextual_help.png
deleted file mode 100644
index dfbcbbe79..000000000
--- a/doc/usermanual/images/contextual_help.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_auto_levels.png b/doc/usermanual/images/darkroom_module_retouch_auto_levels.png
deleted file mode 100644
index fa05cab39..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_auto_levels.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_blur.png b/doc/usermanual/images/darkroom_module_retouch_blur.png
deleted file mode 100644
index 16be05dfe..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_blur.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_clone.png b/doc/usermanual/images/darkroom_module_retouch_clone.png
deleted file mode 100644
index 41cb0ed07..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_clone.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_cut.png b/doc/usermanual/images/darkroom_module_retouch_cut.png
deleted file mode 100644
index 80a61e0d4..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_cut.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_display_scale.png b/doc/usermanual/images/darkroom_module_retouch_display_scale.png
deleted file mode 100644
index 12bab2f8f..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_display_scale.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_fill.png b/doc/usermanual/images/darkroom_module_retouch_fill.png
deleted file mode 100644
index 819039af3..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_fill.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_heal.png b/doc/usermanual/images/darkroom_module_retouch_heal.png
deleted file mode 100644
index b0995685f..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_heal.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_mask.png b/doc/usermanual/images/darkroom_module_retouch_mask.png
deleted file mode 100644
index 7d07610a0..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_mask.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_paste.png b/doc/usermanual/images/darkroom_module_retouch_paste.png
deleted file mode 100644
index 987130cb4..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_paste.png
+++ /dev/null
Binary files differ
diff --git a/doc/usermanual/images/darkroom_module_retouch_switch.png b/doc/usermanual/images/darkroom_module_retouch_switch.png
deleted file mode 100644
index 8ff599e08..000000000
--- a/doc/usermanual/images/darkroom_module_retouch_switch.png
+++ /dev/null
Binary files differ
diff --git a/po/fr.po b/po/fr.po
index 306f2b88f..33fbbca01 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -3738,7 +3738,7 @@ msgstr "nouveau pré-réglage"
msgid "please give preset a name"
msgstr "merci de donner un nom au pré-réglage"
-#: ../src/gui/presets.c:204
+#: ../src/gui/presets.c:228
msgid "unnamed preset"
msgstr "pré-réglage sans nom"
diff --git a/po/hu.po b/po/hu.po
index a28aba25a..c5923cebf 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -3705,7 +3705,7 @@ msgstr "új tárolt beállítás"
msgid "please give preset a name"
msgstr "adja meg a tárolt beállítás nevét"
-#: ../src/gui/presets.c:204
+#: ../src/gui/presets.c:228
msgid "unnamed preset"
msgstr "névtelen tárolt beállítás"
diff --git a/po/nl.po b/po/nl.po
index b726ed64e..795151434 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -1180,7 +1180,7 @@ msgstr "linear Rec709 RGB"
msgid "linear Rec2020 RGB"
msgstr "linear Rec2020 RGB"
-#: ../src/common/colorspaces.c:942 ../src/common/colorspaces.c:1176
+#: ../src/common/colorspaces.c:939 ../src/common/colorspaces.c:1173
msgid "linear XYZ"
msgstr "lineair XYZ"
@@ -1189,39 +1189,39 @@ msgstr "lineair XYZ"
msgid "Lab"
msgstr "Lab"
-#: ../src/common/colorspaces.c:944 ../src/common/colorspaces.c:1188
+#: ../src/common/colorspaces.c:941 ../src/common/colorspaces.c:1185
msgid "linear infrared BGR"
msgstr "lineair infrarood BGR"
-#: ../src/common/colorspaces.c:945 ../src/common/colorspaces.c:1145
+#: ../src/common/colorspaces.c:942 ../src/common/colorspaces.c:1142
msgid "system display profile"
msgstr "systeem weergave profiel"
-#: ../src/common/colorspaces.c:946
+#: ../src/common/colorspaces.c:943
msgid "embedded ICC profile"
msgstr "ingesloten ICC profiel"
-#: ../src/common/colorspaces.c:947
+#: ../src/common/colorspaces.c:944
msgid "embedded matrix"
msgstr "ingesloten matrix"
-#: ../src/common/colorspaces.c:948
+#: ../src/common/colorspaces.c:945
msgid "standard color matrix"
msgstr "standaard kleuren matrix"
-#: ../src/common/colorspaces.c:949
+#: ../src/common/colorspaces.c:946
msgid "enhanced color matrix"
msgstr "verbeterde kleuren matrix"
-#: ../src/common/colorspaces.c:950
+#: ../src/common/colorspaces.c:947
msgid "vendor color matrix"
msgstr "leverancier kleuren matrix"
-#: ../src/common/colorspaces.c:951
+#: ../src/common/colorspaces.c:948
msgid "alternate color matrix"
msgstr "alternatieve kleuren matrix"
-#: ../src/common/colorspaces.c:1151
+#: ../src/common/colorspaces.c:1148
msgid "sRGB (e.g. JPG)"
msgstr "sRGB (b.v. JPG)"
@@ -1229,7 +1229,7 @@ msgstr "sRGB (b.v. JPG)"
msgid "sRGB (web-safe)"
msgstr "sRGB (web-veilig)"
-#: ../src/common/colorspaces.c:1193
+#: ../src/common/colorspaces.c:1190
msgid "BRG (for testing)"
msgstr "BRG (om uit te proberen)"
@@ -3712,7 +3712,7 @@ msgstr "nieuwe voorkeur"
msgid "please give preset a name"
msgstr "geef deze voorkeur een naam"
-#: ../src/gui/presets.c:204
+#: ../src/gui/presets.c:228
msgid "unnamed preset"
msgstr "naamloze voorkeur"
diff --git a/po/ru.po b/po/ru.po
index fc0729877..94cda4a07 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -1662,7 +1662,7 @@ msgstr[2] "ИмпортируетÑÑ %d Ñнимков Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹"
#: ../src/control/jobs/camera_jobs.c:391 ../src/gui/camera_import_dialog.c:211
msgid "import images from camera"
-msgstr "Импортирование Ñнимков Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹"
+msgstr "Импорт Ñнимков Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹"
#: ../src/control/jobs/control_jobs.c:140
msgid "failed to create film roll for destination directory, aborting move.."
@@ -3615,7 +3615,7 @@ msgstr "новый профиль"
msgid "please give preset a name"
msgstr "Дайте профилю название"
-#: ../src/gui/presets.c:204
+#: ../src/gui/presets.c:228
msgid "unnamed preset"
msgstr "БезымÑнный профиль"
@@ -11286,7 +11286,7 @@ msgstr "ÐвторÑкие права (c) принадлежат ÑоздатеÐ
#: ../src/libs/tools/darktable.c:256
msgid "organize and develop images from digital cameras"
-msgstr "ÐžÑ€Ð³Ð°Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ обработка Ñнимков Ñ Ñ†Ð¸Ñ„Ñ€Ð¾Ð²Ñ‹Ñ… фотокамер"
+msgstr "ÐžÑ€Ð³Ð°Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ обработка цифровых фотографий"
#: ../src/libs/tools/darktable.c:271
msgid "translator-credits"
@@ -11412,7 +11412,7 @@ msgstr "Свернуть Ñгруппированные Ñнимки"
#: ../src/libs/tools/global_toolbox.c:102 ../src/libs/tools/global_toolbox.c:164
msgid "hide image overlays"
-msgstr "Скрыть дополнительную информацию о Ñнимках"
+msgstr "Скрыть подÑказки о Ñнимках"
#: ../src/libs/tools/global_toolbox.c:104 ../src/libs/tools/global_toolbox.c:166
msgid "show image overlays"
diff --git a/po/sl.po b/po/sl.po
index 167175b28..b61bc4667 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -139,8 +139,8 @@ msgid ""
"check this option to not use the embedded JPEG from the raw file but process "
"the raw data. this is slower but gives you color managed thumbnails."
msgstr ""
-"odkljukajte to možnost, da ne uporabimo vgrajene JPEG sliÄica surove slike "
-"ampak obdelamo sliko v surovem formatu. to je poÄasnejÅ¡e, a rezultat je "
+"odkljukajte to možnost, da se ne uporabi vgrajena JPEG sliÄica surove slike "
+"ampak se obdela slika v surovem formatu. To je poÄasnejÅ¡e, a rezultat je "
"predogledna sliÄica v kontroliranih barvah."
#: ../build/src/preferences_gen.h:1736
@@ -227,7 +227,7 @@ msgstr "Å¡tevilo ravni map prikazanih v seznamu map s filmi, zaÄeto z desne"
#: ../build/src/preferences_gen.h:1883
msgid "ignore JPEG images when importing film rolls"
-msgstr "izpusti slike v formatu JPEG kadar uvažamo zvitke filmov"
+msgstr "izpusti slike v formatu JPEG kadar uvažaš zvitke filmov"
#: ../build/src/preferences_gen.h:1895
msgid ""
@@ -239,7 +239,7 @@ msgstr ""
#: ../build/src/preferences_gen.h:1903
msgid "recursive directory traversal when importing filmrolls"
-msgstr "rekurzivni sprehod po mapah, ko uvažamo zvitke filmov"
+msgstr "rekurzivni sprehod po mapah kadar uvažam zvitke filmov"
#: ../build/src/preferences_gen.h:1922
msgid "creator to be applied when importing"
@@ -251,7 +251,7 @@ msgstr "izdajatelj slik, ki naj bo oznaÄen po uvažanju"
#: ../build/src/preferences_gen.h:1968
msgid "rights to be applied when importing"
-msgstr "avtorske pravice slik, ki naj bodo oznaÄene po uvažanju"
+msgstr "avtorske pravice slik, ki naj bo oznaÄene po uvažanju"
#: ../build/src/preferences_gen.h:1991
msgid "comma separated tags to be applied when importing"
@@ -327,8 +327,8 @@ msgid ""
"if the thumbnail size is greater than this value, it will be processed using "
"the full quality rendering path (better but slower)."
msgstr ""
-"Äe je velikost predogledne sliÄice veÄja od te vrednosti, bo sliÄica izdelana "
-"iz mape, kjer so najkakovostnejÅ¡i originali (bolje a poÄasnejÅ¡e)."
+"Äe je velikost predogledne sliÄice veÄja od te vrednosti, bi sliÄica izdelana "
+"mape, kjer so iz najkakovostnejÅ¡i originali (bolje a poÄasnejÅ¡e)."
#: ../build/src/preferences_gen.h:2140
msgid "enable extended thumb overlay"
@@ -4833,8 +4833,8 @@ msgid ""
"shift-click to only fit lens shift"
msgstr ""
"avtomatiÄno popravi popaÄenja vertikalne perspektive\n"
-"ctrl-klik samo za prilagajanje rotacije\n"
-"shift-klik samo za prilagajanje zamika leÄja"
+"ctrl-click samo za prilagajanje rotacije\n"
+"shift-click samo za prilagajanje zamika leÄja"
#: ../src/iop/ashift.c:4841
msgid ""
@@ -4843,8 +4843,8 @@ msgid ""
"shift-click to only fit lens shift"
msgstr ""
"avtomatiÄno popravljanje popaÄenja horizontalne perspektive\n"
-"ctrl-klik samo za prilagajanje rotacije\n"
-"shift-klik samo za prilagajanje zamika leÄja"
+"ctrl-click samo za prilagajanje rotacije\n"
+"shift-click samo za prilagajanje zamika leÄja"
#: ../src/iop/ashift.c:4844
msgid ""
@@ -4856,8 +4856,8 @@ msgid ""
msgstr ""
"avtomatiÄno popravljanje popaÄenj vertikalne in horizontalne perspektive; "
"prilagajanje rotacije, zamika leÄja v obeh smereh in striženja\n"
-"ctrl-klik samo za prilagajanje rotacije\n"
-"shift-klik samo za prilagajanje zamika leÄja ctrl-shift-klik samo za "
+"ctrl-click samo za prilagajanje rotacije\n"
+"shift-click samo za prilagajanje zamika leÄja ctrl-shift-click samo za "
"prilagajanje rotacije in zamika leÄja"
#: ../src/iop/ashift.c:4850
@@ -4868,9 +4868,9 @@ msgid ""
"ctrl-shift-click for a combination of both methods"
msgstr ""
"analiza strukture linij slike\n"
-"ctrl-klik za dodatne izboljšave robov\n"
-"shift-klik za odatne izboljšave podrobnosti\n"
-"ctrl-shift-klik za kombinacijo obeh metod"
+"ctrl-click za dodatne izboljšave robov\n"
+"shift-click za odatne izboljšave podrobnosti\n"
+"ctrl-shift-click za kombinacijo obeh metod"
#: ../src/iop/ashift.c:4854
msgid "remove line structure information"
@@ -4950,7 +4950,7 @@ msgstr "krepko"
#: ../src/iop/atrous.c:1451
msgid "dull"
-msgstr "medlo"
+msgstr "zamegljeno"
#: ../src/iop/atrous.c:1664 ../src/iop/equalizer.c:389 ../src/iop/nlmeans.c:854
msgid "luma"
@@ -4966,7 +4966,7 @@ msgstr "barvitost"
#: ../src/iop/atrous.c:1671
msgid "change color saturation at each feature size"
-msgstr "spremeni nasiÄenost barv pri vsaki velikosti"
+msgstr "spremeni nasiÄenost barv pri vsaki možnosti"
#: ../src/iop/atrous.c:1673
msgid "edges"
@@ -5084,14 +5084,14 @@ msgstr "linearno"
#: ../src/iop/basecurve.c:1935 ../src/iop/profile_gamma.c:851
msgid "logarithmic"
-msgstr "logaritemsko"
+msgstr "logaritmiÄno"
#: ../src/iop/basecurve.c:1936 ../src/iop/tonecurve.c:1261
msgid ""
"scale to use in the graph. use logarithmic scale for more precise control "
"near the blacks"
msgstr ""
-"merilo pri grafih. uporabljajte logaritemsko merilo za natanÄnejÅ¡e "
+"merilo pri grafih. uporabljajte logaritmiÄno merilo za natanÄnejÅ¡e "
"upravljanje Ärnin"
#: ../src/iop/basecurve.c:1942
@@ -5685,7 +5685,7 @@ msgstr "kot"
#: ../src/iop/clipping.c:1880
msgid "right-click and drag a line on the image to drag a straight line"
msgstr ""
-"kliknite z desno tipko in povlecite Ärto na sliki, da se poravna z ravno Ärto "
+"kliknite z desno tipko in povlecite Ärto na sliki da se poravna z ravno Ärto "
"na sliki"
#: ../src/iop/clipping.c:1884
@@ -6084,7 +6084,7 @@ msgstr ""
"klik za izbiro\n"
"dvojni klik za ponastavitev\n"
"desni klik za brisanje krpe\n"
-"shift-klik ob izbiri barve za zamenjavo krpe"
+"shift-click ob izbiri barve za zamenjavo krpe"
#: ../src/iop/colorchecker.c:1282
msgid "patch"
@@ -7372,7 +7372,7 @@ msgstr "zrnatost"
#: ../src/iop/grain.c:625
msgid "the grain size (~ISO of the film)"
-msgstr "velikost zrna (~ISO filma)"
+msgstr "velikost zrna (~ISO film)"
#: ../src/iop/grain.c:633
msgid "the strength of applied grain"
@@ -8434,7 +8434,7 @@ msgstr "premik toÄke beline"
#: ../src/iop/shadhi.c:856
msgid "filter to use for softening. bilateral avoids halos"
-msgstr "filter za mehÄanje. bilateralni se izogne kolobarjem"
+msgstr "filter za mehÄanje. bilateralna raba se izogne odsevom"
#: ../src/iop/shadhi.c:857
msgid ""
@@ -9096,7 +9096,7 @@ msgstr "moÄ nasiÄenja"
#: ../src/iop/velvia.c:387
msgid "mid-tones bias"
-msgstr "strmina srednjih tonov"
+msgstr "poudarjanje srednjih tonov"
#: ../src/iop/velvia.c:391
msgid "how much to spare highlights and shadows"
@@ -9263,7 +9263,7 @@ msgstr "oznaÄevalnik"
#: ../src/iop/watermark.c:1329
#, c-format
msgid "SVG watermarks in %s/watermarks or %s/watermarks"
-msgstr "SVG vodni žigi v %s/watermarks ali %s/watermarks"
+msgstr "SVG vodni žigi v %s/vodni žigi ali %s/vodni žigi"
#: ../src/iop/watermark.c:1346
msgid ""
@@ -9275,7 +9275,7 @@ msgstr ""
#: ../src/iop/watermark.c:1349
msgid "select watermark color"
-msgstr "izbira barve vodnega žiga"
+msgstr "izbira barve vodnega tiska"
#. Simple text
#: ../src/iop/watermark.c:1355
@@ -10125,11 +10125,11 @@ msgstr "stisni sklad zgodovine"
msgid "compress history stack"
msgstr "stisni sklad zgodovine"
-#: ../src/libs/history.c:114
+#: ../src/libs/history.c:115
msgid "create a minimal history stack which produces the same image"
msgstr "ustvari najmanjši sklad zgodovine, ki izdela enako sliko"
-#: ../src/libs/history.c:122
+#: ../src/libs/history.c:123
msgid "create a style from the current history stack"
msgstr "ustvari slog iz trenutnega sklada zgodovine"
@@ -10211,7 +10211,7 @@ msgstr "kopiraj sliko lokalno"
#: ../src/libs/image.c:254
msgid "resync local copy"
-msgstr "resinhr. lok. kopijo"
+msgstr "resinhroniziraj lokalno kopijo"
#: ../src/libs/image.c:257
msgid "synchronize the image's XMP and remove the local copy"
@@ -10759,7 +10759,7 @@ msgstr "zastavice"
#: ../src/libs/metadata_view.c:112
msgid "focus distance"
-msgstr "izmerjena razdalja"
+msgstr "goriÅ¡Äna razdalja"
#: ../src/libs/metadata_view.c:114
msgid "datetime"
diff --git a/src/external/rawspeed/.ci/Dockerfile b/src/external/rawspeed/.ci/Dockerfile
index 1d00e2441..742342ff1 100644
--- a/src/external/rawspeed/.ci/Dockerfile
+++ b/src/external/rawspeed/.ci/Dockerfile
@@ -36,21 +36,21 @@ RUN echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes
# Fix broken packages
RUN echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissin
-ENV GCC_VER=7
-ENV LLVM_VER=6.0
+ENV GCC_VER=8
+ENV LLVM_VER=7
# pls keep sorted :)
RUN rm -rf /var/lib/apt/lists/* && apt-get update && \
- apt-get install \
- clang++-$LLVM_VER clang-tidy-$LLVM_VER clang-tools-$LLVM_VER \
- cmake curl default-jdk-headless default-jre-headless dirmngr doxygen \
- g++-$GCC_VER git gnupg googletest graphviz libjpeg-dev libpugixml-dev \
+ apt-get install clang++-$LLVM_VER clang-tidy-$LLVM_VER \
+ clang-tools-$LLVM_VER cmake curl default-jdk-headless default-jre-headless \
+ dirmngr doxygen g++-$GCC_VER git gnupg googletest graphviz \
+ libc++-$LLVM_VER-dev libjpeg-dev libomp-$LLVM_VER-dev libpugixml-dev \
libxml2-utils make ninja-build python3-sphinx python3-sphinx-rtd-theme \
unzip zlib1g-dev && apt-get clean && rm -rf /var/lib/apt/lists/*
# sonarqube support.
-ENV SONAR_SCANNER_CLI_VERSION=3.0.3.778-linux \
+ENV SONAR_SCANNER_CLI_VERSION=3.2.0.1227-linux \
SONARQUBE_HOME=/opt/sonarqube
RUN set -x \
@@ -61,8 +61,8 @@ RUN set -x \
# sub 2048R/06855C1D 2015-05-25
&& gpg --keyserver keys.gnupg.net --recv-keys F1182E81C792928921DBCAB4CFCA4A29D26468DE \
&& cd /opt \
- && curl -o sonar-scanner-cli.zip -fSL https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_CLI_VERSION.zip \
- && curl -o sonar-scanner-cli.zip.asc -fSL https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_CLI_VERSION.zip.asc \
+ && curl -o sonar-scanner-cli.zip -fSL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_CLI_VERSION.zip \
+ && curl -o sonar-scanner-cli.zip.asc -fSL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_CLI_VERSION.zip.asc \
&& gpg --batch --verify sonar-scanner-cli.zip.asc sonar-scanner-cli.zip \
&& unzip sonar-scanner-cli.zip \
&& mv sonar-scanner-$SONAR_SCANNER_CLI_VERSION $SONARQUBE_HOME \
diff --git a/src/external/rawspeed/.ci/ci-script.sh b/src/external/rawspeed/.ci/ci-script.sh
index 5444261a5..8f639233e 100755
--- a/src/external/rawspeed/.ci/ci-script.sh
+++ b/src/external/rawspeed/.ci/ci-script.sh
@@ -111,7 +111,7 @@ case "$FLAVOR" in
"Coverage")
handle_coverage_data
- substring="ENABLE_SAMPLEBASED_TESTING"
+ substring="RAWSPEED_ENABLE_SAMPLE_BASED_TESTING"
if [ "${ECO#*$substring}" != "$ECO" ];
then
handle_sample_coverage_data
diff --git a/src/external/rawspeed/.clang-tidy b/src/external/rawspeed/.clang-tidy
index a986d7883..6d77ef287 100644
--- a/src/external/rawspeed/.clang-tidy
+++ b/src/external/rawspeed/.clang-tidy
@@ -1,5 +1,5 @@
---
-Checks: '*,-clang-analyzer-*,-clang-diagnostic-*,-cert-dcl50-cpp,-cert-env33-c,-cert-err58-cpp,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-google-default-arguments,-google-readability-todo,-google-runtime-int,-hicpp-member-init,-hicpp-special-member-functions,-llvm-header-guard,-llvm-include-order,-misc-unused-parameters,-readability-implicit-bool-cast,-readability-inconsistent-declaration-parameter-name,-android-*,-hicpp-braces-around-statements,-hicpp-function-size,-google-readability-braces-around-statements,-google-readability-function-size,-readability-implicit-bool-conversion,-hicpp-signed-bitwise,-hicpp-no-array-decay,-hicpp-vararg,-hicpp-multiway-paths-covered,-cppcoreguidelines-owning-memory,-fuchsia-*,-portability-simd-intrinsics'
+Checks: '*,-clang-analyzer-*,-clang-diagnostic-*,-cert-dcl50-cpp,-cert-env33-c,-cert-err58-cpp,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-google-default-arguments,-google-readability-todo,-google-runtime-int,-hicpp-member-init,-hicpp-special-member-functions,-llvm-header-guard,-llvm-include-order,-misc-unused-parameters,-readability-implicit-bool-cast,-readability-inconsistent-declaration-parameter-name,-android-*,-hicpp-braces-around-statements,-hicpp-function-size,-google-readability-braces-around-statements,-google-readability-function-size,-readability-implicit-bool-conversion,-hicpp-signed-bitwise,-hicpp-no-array-decay,-hicpp-vararg,-hicpp-multiway-paths-covered,-cppcoreguidelines-owning-memory,-fuchsia-*,-portability-simd-intrinsics,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-misc-non-private-member-variables-in-classes,-cppcoreguidelines-non-private-member-variables-in-classes'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
@@ -8,17 +8,17 @@ CheckOptions:
- key: readability-braces-around-statements.ShortStatementLines
value: '3'
- key: readability-function-size.BranchThreshold
- value: '26'
+ value: '27'
- key: readability-function-size.LineThreshold
- value: '160'
+ value: '167'
- key: readability-function-size.StatementThreshold
- value: '135'
+ value: '136'
- key: readability-function-size.ParameterThreshold
value: '7'
- key: readability-function-size.NestingThreshold
value: '6'
- key: readability-function-size.VariableThreshold
- value: '30'
+ value: '32'
- key: readability-simplify-boolean-expr.ChainedConditionalAssignment
value: '1'
- key: readability-simplify-boolean-expr.ChainedConditionalReturn
@@ -39,4 +39,8 @@ CheckOptions:
value: lower_case
- key: google-runtime-references.WhiteListTypes
value: 'benchmark::State'
+ - key: modernize-use-default-member-init.UseAssignment
+ value: 1
+ - key: cppcoreguidelines-macro-usage.AllowedRegexp
+ value: 'DEBUG|_GLIBCXX_SANITIZE_VECTOR|CMAKE_SOURCE_DIR|STR|XSTR|BUFFER_PADDING|BSWAP16|BSWAP32|BSWAP64|ThrowExceptionHelper|ThrowIOE|ThrowRSE|ThrowCME|ThrowRDE|ThrowRPE|ThrowTPE|ThrowFIE|ThrowCPE|ThrowFPE|DECODER|fuji_quant_gradient|JPEG_MEMSRC|RLVTABLE|PRECISION_MIN|PRECISION_MAX|MARKER_BAND_END|SQR|RS_CAMERAS_XML_PATH|FULLDECODE|IMPL|IMPL0|IMPL1|PUMP|DECODE|PARSER|GEN_E|GEN_PFS|GEN_PSS|BENCHMARK_CAPTURE_NAME'
...
diff --git a/src/external/rawspeed/.mailmap b/src/external/rawspeed/.mailmap
index 10506e1b3..b7aafe52e 100644
--- a/src/external/rawspeed/.mailmap
+++ b/src/external/rawspeed/.mailmap
@@ -17,3 +17,5 @@ Peter Budai <peterbudai@hotmail.com> peterbud <peterbudai@hotmail.com>
Matthieu Volat <mazhe@alkumuna.eu>
Matthieu Volat <mazhe@alkumuna.eu> Matthieu <mazhe@alkumuna.eu>
Matthieu Volat <mazhe@alkumuna.eu> Matthieu Volat <matthieu.volat@ujf-grenoble.fr>
+
+Shita Yuuma <m@crat.jp>
diff --git a/src/external/rawspeed/.travis.yml b/src/external/rawspeed/.travis.yml
index 559d8f061..604fc7175 100644
--- a/src/external/rawspeed/.travis.yml
+++ b/src/external/rawspeed/.travis.yml
@@ -69,13 +69,13 @@ jobs:
sudo: required
services:
- docker
- env: CC=gcc-7 CXX=g++-7
+ env: CC=gcc-8 CXX=g++-8
- os: linux
dist: trusty
sudo: required
services:
- docker
- env: CC=gcc-7 CXX=g++-7 GCOV=gcov-7 FLAVOR=Coverage ECO="-DENABLE_SAMPLEBASED_TESTING=ON" EXTRA_OPTS="$DOCKER_RPUU"
+ env: CC=gcc-8 CXX=g++-8 GCOV=gcov-8 FLAVOR=Coverage ECO="-DRAWSPEED_ENABLE_SAMPLE_BASED_TESTING=ON" EXTRA_OPTS="$DOCKER_RPUU"
cache:
directories:
- '$HOME/$RPUU_DST'
@@ -88,36 +88,37 @@ jobs:
sudo: required
services:
- docker
- env: CC=clang-6.0 CXX=clang++-6.0 TARGET=STATICANALYSIS ECO="-DUSE_CLANG_TIDY=ON"
+ env: CC=clang-7 CXX=clang++-7 TARGET=STATICANALYSIS ECO="-DUSE_CLANG_TIDY=ON -DWITH_OPENMP=OFF"
- os: linux
dist: trusty
sudo: required
services:
- docker
- env: CC=clang-6.0 CXX=clang++-6.0 ECO="-DWITH_PTHREADS=OFF"
+ env: CC=clang-7 CXX=clang++-7 ECO="-DWITH_PTHREADS=OFF -DWITH_OPENMP=OFF"
- os: linux
dist: trusty
sudo: required
env: CC=gcc-5 CXX=g++-5 EXTRA=NODOCKER
- - stage: deploy
- os: linux
- dist: trusty
- sudo: required
- services:
- - docker
- env: CC=gcc-7 CXX=g++-7 GCOV=gcov-7 TARGET=SONARQUBE FLAVOR=Coverage ECO="-DENABLE_SAMPLEBASED_TESTING=ON" EXTRA_OPTS="--tmpfs /root/.sonar --volume $HOME/.sonar/cache:/root/.sonar/cache $DOCKER_RPUU"
- git:
- depth: 9999999
- cache:
- directories:
- - '$HOME/$RPUU_DST'
- - '$HOME/.sonar/cache'
+ #- stage: deploy
+ # os: linux
+ # sudo: required
+ # dist: xenial
+ # edge: true
+ # services:
+ # - docker
+ # env: CC=gcc-8 CXX=g++-8 GCOV=gcov-8 TARGET=SONARQUBE FLAVOR=Coverage ECO="-DRAWSPEED_ENABLE_SAMPLE_BASED_TESTING=ON" EXTRA_OPTS="--tmpfs /root/.sonar --volume $HOME/.sonar/cache:/root/.sonar/cache $DOCKER_RPUU"
+ # git:
+ # depth: 9999999
+ # cache:
+ # directories:
+ # - '$HOME/$RPUU_DST'
+ # - '$HOME/.sonar/cache'
- os: linux
dist: trusty
sudo: required
services:
- docker
- env: CC=clang-6.0 CXX=clang++-6.0 TARGET=WWW
+ env: CC=clang-7 CXX=clang++-7 TARGET=WWW ECO="-DWITH_OPENMP=OFF"
# linux clang Coverage build OOM's in gcov during final codecov report collection
# OSX gcc Coverage build produces invalid .gcno files
@@ -146,7 +147,7 @@ script:
export CMD="$SRC_DIR/.ci/ci-script.sh";
if [[ "$TARGET" == "STATICANALYSIS" ]]; then
export TARGET="build";
- export CMD="scan-build-6.0 --use-cc=\"$CC\" --use-c++=\"$CXX\" --force-analyze-debug-code --status-bugs -disable-checker deadcode.DeadStores $CMD";
+ export CMD="scan-build-7 --use-cc=\"$CC\" --use-c++=\"$CXX\" --force-analyze-debug-code --status-bugs -disable-checker deadcode.DeadStores $CMD";
fi;
if [[ "$TARGET" == "SONARQUBE" ]]; then
export TARGET="build";
@@ -156,7 +157,7 @@ script:
docker run --read-only --tmpfs /tmp --volume $TRAVIS_BUILD_DIR:$SRC_DIR:ro --volume "$TRAVIS_BUILD_DIR/build":$BUILD_DIR --workdir $BUILD_DIR --tmpfs $INSTALL_PREFIX $EXTRA_TMPFS $EXTRA_OPTS --env CC --env CXX --env GCOV --env CFLAGS --env CXXFLAGS --env SRC_DIR --env BUILD_DIR --env INSTALL_PREFIX --env TARGET --env FLAVOR --env ECO darktable/rawspeed sh -c "$CMD";
if [[ "$TARGET2" == "SONARQUBE" ]]; then
- export CMD="sonar-scanner -X -Dproject.settings=\"$SRC_DIR/.ci/sonar-project.properties\" -Dsonar.login=\"$SONAR_TOKEN\" -Dsonar.branch=\"$TRAVIS_BRANCH\" -Dsonar.projectVersion=\"$TRAVIS_COMMIT\"";
+ export CMD="sonar-scanner -Dproject.settings=\"$SRC_DIR/.ci/sonar-project.properties\" -Dsonar.login=\"$SONAR_TOKEN\" -Dsonar.projectVersion=\"$TRAVIS_COMMIT\"";
docker run --read-only --tmpfs /tmp --volume $TRAVIS_BUILD_DIR:$SRC_DIR:ro --volume "$TRAVIS_BUILD_DIR/build":$BUILD_DIR --workdir $SRC_DIR --tmpfs $INSTALL_PREFIX $EXTRA_TMPFS $EXTRA_OPTS --env CC --env CXX --env GCOV --env CFLAGS --env CXXFLAGS --env SRC_DIR --env BUILD_DIR --env INSTALL_PREFIX --env TARGET --env FLAVOR --env ECO darktable/rawspeed sh -c "$CMD";
fi;
diff --git a/src/external/rawspeed/CMakeLists.txt b/src/external/rawspeed/CMakeLists.txt
index 5d8638595..9248d29a4 100644
--- a/src/external/rawspeed/CMakeLists.txt
+++ b/src/external/rawspeed/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.4.0)
cmake_policy(SET CMP0011 NEW)
cmake_policy(SET CMP0025 NEW)
@@ -24,12 +24,7 @@ endif()
include(GNUInstallDirs)
include(FeatureSummary)
-if(NOT (CMAKE_VERSION VERSION_LESS 3.4.0-rc1))
- project(rawspeed CXX)
-else()
- # FindThreads.cmake issue
- project(rawspeed CXX C)
-endif()
+project(rawspeed CXX)
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH})
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
@@ -51,8 +46,23 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL
else()
set(RAWSPEED_USE_LIBCXX OFF CACHE BOOL "(Clang only) Build using libc++ as the standard library." FORCE)
endif()
+option(RAWSPEED_ENABLE_DEBUG_INFO "Whether to generate debug info or not." ON)
+option(RAWSPEED_ENABLE_WERROR "Stop and fail the build, if a compiler warning is triggered." ON)
option(WITH_PTHREADS "Enable threading support through pthread. Highly recommended" ON)
-option(WITH_OPENMP "Enable OpenMP support. Only used for tools, not the library itself." ON)
+
+option(WITH_OPENMP "Enable OpenMP support." ON)
+if(WITH_OPENMP)
+ option(USE_BUNDLED_LLVMOPENMP "Build and use LLVM OpenMP runtime library in-tree" OFF)
+else()
+ set(USE_BUNDLED_LLVMOPENMP OFF CACHE BOOL "Build and use LLVM OpenMP runtime library in-tree" FORCE)
+endif()
+set(LLVMOPENMP_PATH "/usr/src/openmp" CACHE PATH "Path to the LLVM OpenMP runtime library root tree.")
+if(WITH_OPENMP AND USE_BUNDLED_LLVMOPENMP)
+ option(ALLOW_DOWNLOADING_LLVMOPENMP "If LLVM OpenMP runtime library src tree is not found in location specified by LLVMOPENMP_PATH, do fetch the archive from internet" OFF)
+else()
+ set(ALLOW_DOWNLOADING_LLVMOPENMP OFF CACHE BOOL "If LLVM OpenMP runtime library src tree is not found in location specified by LLVMOPENMP_PATH, do fetch the archive from internet" FORCE)
+endif()
+
option(WITH_PUGIXML "Enable XML support for cameras.xml reading" ON)
if(WITH_PUGIXML)
option(USE_BUNDLED_PUGIXML "Build and use pugixml in-tree" OFF)
@@ -94,10 +104,10 @@ else()
endif()
option(BUILD_DOCS "Build the documentation (Sphinx+Doxygen)." OFF)
option(BUILD_FUZZERS "Build the fuzzing tree." ON)
-if(BUILD_TOOLS AND BUILD_TESTING)
- option(ENABLE_SAMPLEBASED_TESTING "If enabled, allows to use rstest to check the samples specified by REFERENCE_SAMPLE_ARCHIVE" OFF)
+if(BUILD_TOOLS)
+ option(RAWSPEED_ENABLE_SAMPLE_BASED_TESTING "If enabled, allows to use rstest to check the samples specified by RAWSPEED_REFERENCE_SAMPLE_ARCHIVE" OFF)
else()
- set(ENABLE_SAMPLEBASED_TESTING OFF CACHE BOOL "If enabled, allows to use rstest to check the samples specified by REFERENCE_SAMPLE_ARCHIVE" FORCE)
+ set(RAWSPEED_ENABLE_SAMPLE_BASED_TESTING OFF CACHE BOOL "If enabled, allows to use rstest to check the samples specified by RAWSPEED_REFERENCE_SAMPLE_ARCHIVE" FORCE)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
option(USE_LLVM_OPT_REPORT "(Clang only) Save compiler optimizations records and show them" OFF)
@@ -117,7 +127,10 @@ set(GOOGLEBENCHMARK_PATH "/usr/src/googlebenchmark" CACHE PATH
set(LIB_FUZZING_ENGINE "OFF" CACHE STRING "Either OFF, or overrides location of prebuilt fuzzing engine library (e.g. libFuzzer) that needs to be linked with all fuzz targets.")
-set(REFERENCE_SAMPLE_ARCHIVE "~/raw-camera-samples/raw.pixls.us-unique" CACHE PATH "The location of the reference sample set to use. Should contain filelist.sha1 and timestamp.txt")
+set(RAWSPEED_REFERENCE_SAMPLE_ARCHIVE "~/raw-camera-samples/raw.pixls.us-unique" CACHE PATH "The location of the reference sample set to use. Should contain filelist.sha1 and timestamp.txt")
+
+set(RAWSPEED_PROFDATA_FILE "${PROJECT_BINARY_DIR}/rawspeed.profdata"
+ CACHE FILEPATH "The location of the .profdata file")
option(RAWSPEED_ENABLE_LTO "Add appropriate flag to the compile and link command lines, enabling link-time optimization." OFF)
@@ -175,15 +188,20 @@ add_custom_target(dependencies ALL)
add_custom_target(tests ALL)
include(compiler-warnings)
-set_directory_properties(PROPERTIES COMPILE_OPTIONS "-Werror")
+
+if(RAWSPEED_ENABLE_WERROR)
+ set_directory_properties(PROPERTIES COMPILE_OPTIONS "-Werror")
+endif()
if(BUILD_BENCHMARKING)
add_custom_target(benchmarks ALL)
endif()
-add_subdirectory(src)
+add_library(rawspeed STATIC)
+
+include(src-dependencies)
-include(OpenMP)
+add_subdirectory(src)
if(BUILD_TESTING)
add_subdirectory(test)
@@ -219,7 +237,7 @@ if(BUILD_TESTING AND CMAKE_BUILD_TYPE STREQUAL "COVERAGE")
include(genhtml)
include(gcc-coverage)
else()
- message(WARNING "Did not find lcov and genhtml."
+ message(WARNING "Did not find lcov and genhtml. "
"Will not be able to generate HTML reports")
endif()
endif()
diff --git a/src/external/rawspeed/README.rst b/src/external/rawspeed/README.rst
index 4f7ff7fdb..3f6640de7 100644
--- a/src/external/rawspeed/README.rst
+++ b/src/external/rawspeed/README.rst
@@ -80,8 +80,8 @@ The main objectives were to make a very fast loader that worked for 75% of the c
RawSpeed is not at the moment a separate library, so you have to include it in your project directly.
-Please see <http://rawspeed.org/> for documentation.
-Doxygen-generated documentation is available at <http://rawspeed.org/doxygen>
+Please see <https://rawspeed.org/> for documentation.
+Doxygen-generated documentation is available at <https://rawspeed.org/doxygen>
Submitting Requests and Patches
--------------------------------------------------------------------------------
diff --git a/src/external/rawspeed/bench/librawspeed/CMakeLists.txt b/src/external/rawspeed/bench/librawspeed/CMakeLists.txt
index b7c1c3f35..05214fc37 100644
--- a/src/external/rawspeed/bench/librawspeed/CMakeLists.txt
+++ b/src/external/rawspeed/bench/librawspeed/CMakeLists.txt
@@ -9,10 +9,6 @@ target_link_libraries(rawspeed_bench PUBLIC rawspeed)
target_link_libraries(rawspeed_bench PUBLIC benchmark)
target_include_directories(rawspeed_bench PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
-if(WITH_OPENMP AND OPENMP_FOUND AND TARGET OpenMP::OpenMP)
- target_link_libraries(rawspeed_bench PUBLIC OpenMP::OpenMP)
-endif()
-
function(add_rs_bench src)
get_filename_component(BENCHNAME ${src} NAME_WE)
add_executable(${BENCHNAME} ${src})
@@ -23,6 +19,8 @@ function(add_rs_bench src)
endfunction()
add_subdirectory(bench)
+add_subdirectory(common)
add_subdirectory(decompressors)
add_subdirectory(interpolators)
add_subdirectory(io)
+add_subdirectory(metadata)
diff --git a/src/external/rawspeed/bench/librawspeed/bench/Common.cpp b/src/external/rawspeed/bench/librawspeed/bench/Common.cpp
index ca2871bca..ea6c2286d 100644
--- a/src/external/rawspeed/bench/librawspeed/bench/Common.cpp
+++ b/src/external/rawspeed/bench/librawspeed/bench/Common.cpp
@@ -28,7 +28,8 @@ using rawspeed::iPoint2D;
using rawspeed::roundUp;
using std::sqrt;
-iPoint2D __attribute__((const)) areaToRectangle(size_t area, iPoint2D aspect) {
+iPoint2D __attribute__((const, visibility("default")))
+areaToRectangle(size_t area, iPoint2D aspect) {
double sqSide = sqrt(area);
double sqARatio =
sqrt(static_cast<double>(aspect.x) / static_cast<double>(aspect.y));
diff --git a/src/external/rawspeed/bench/librawspeed/common/CMakeLists.txt b/src/external/rawspeed/bench/librawspeed/common/CMakeLists.txt
new file mode 100644
index 000000000..844506e01
--- /dev/null
+++ b/src/external/rawspeed/bench/librawspeed/common/CMakeLists.txt
@@ -0,0 +1,7 @@
+FILE(GLOB RAWSPEED_BENCHS_SOURCES
+ "DefaultInitAllocatorAdaptorBenchmark.cpp"
+)
+
+foreach(IN ${RAWSPEED_BENCHS_SOURCES})
+ add_rs_bench(${IN})
+endforeach()
diff --git a/src/external/rawspeed/bench/librawspeed/common/DefaultInitAllocatorAdaptorBenchmark.cpp b/src/external/rawspeed/bench/librawspeed/common/DefaultInitAllocatorAdaptorBenchmark.cpp
new file mode 100644
index 000000000..e70a6607c
--- /dev/null
+++ b/src/external/rawspeed/bench/librawspeed/common/DefaultInitAllocatorAdaptorBenchmark.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; 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/DefaultInitAllocatorAdaptor.h" // for DefaultInitAllocatorAd...
+#include <benchmark/benchmark.h> // for Benchmark, BENCHMARK_...
+#include <memory> // for allocator
+#include <vector> // for vector
+
+using Type = int;
+
+template <typename Allocator> static void construct(benchmark::State& state) {
+ std::vector<Type, Allocator> vec(state.range(0));
+ benchmark::DoNotOptimize(vec);
+}
+
+template <typename Allocator>
+static void construct_with_zeroinit(benchmark::State& state) {
+ std::vector<Type, Allocator> vec(state.range(0), Type(0));
+ benchmark::DoNotOptimize(vec);
+}
+
+template <typename Worker>
+void BM_std_vector(benchmark::State& state, Worker&& worker) {
+ // Do it once outside of the loop to maybe offset the initial alloc time.
+ worker(state);
+
+ for (auto _ : state)
+ worker(state);
+
+ const auto AllocSize = sizeof(Type) * state.range(0);
+ state.counters["Allocation,bytes"] = AllocSize;
+ state.SetComplexityN(AllocSize);
+ state.SetBytesProcessed(AllocSize * state.iterations());
+ state.SetItemsProcessed(state.range(0) * state.iterations());
+}
+
+static void CustomArguments(benchmark::internal::Benchmark* b) {
+ b->RangeMultiplier(2)
+ ->Range(1U << 0U, 1U << 31U)
+ ->Complexity(benchmark::BigO::oN);
+}
+
+#define BENCHMARK_CAPTURE_NAME(func, ...) \
+ BENCHMARK_CAPTURE(func, #__VA_ARGS__, __VA_ARGS__)
+
+BENCHMARK_CAPTURE_NAME(BM_std_vector, construct<std::allocator<int>>)
+ ->Apply(CustomArguments);
+BENCHMARK_CAPTURE_NAME(
+ BM_std_vector,
+ construct<rawspeed::DefaultInitAllocatorAdaptor<int, std::allocator<int>>>)
+ ->Apply(CustomArguments);
+
+BENCHMARK_CAPTURE_NAME(BM_std_vector,
+ construct_with_zeroinit<std::allocator<int>>)
+ ->Apply(CustomArguments);
+BENCHMARK_CAPTURE_NAME(
+ BM_std_vector,
+ construct_with_zeroinit<
+ rawspeed::DefaultInitAllocatorAdaptor<int, std::allocator<int>>>)
+ ->Apply(CustomArguments);
+
+BENCHMARK_MAIN();
diff --git a/src/external/rawspeed/bench/librawspeed/decompressors/DeflateDecompressorBenchmark.cpp b/src/external/rawspeed/bench/librawspeed/decompressors/DeflateDecompressorBenchmark.cpp
index f238c0b77..d2dfdbf3f 100644
--- a/src/external/rawspeed/bench/librawspeed/decompressors/DeflateDecompressorBenchmark.cpp
+++ b/src/external/rawspeed/bench/librawspeed/decompressors/DeflateDecompressorBenchmark.cpp
@@ -26,12 +26,12 @@
#include "common/RawImage.h" // for RawImage, RawImageData
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include <algorithm> // for move
#include <benchmark/benchmark.h> // for Benchmark, BENCHMARK_...
#include <cassert> // for assert
#include <cstddef> // for size_t
#include <memory> // for unique_ptr
#include <type_traits> // for integral_constant
+#include <utility> // for move
#include <zlib.h>
#ifndef NDEBUG
@@ -109,14 +109,15 @@ static inline void BM_DeflateDecompressor(benchmark::State& state) {
break;
}
- std::unique_ptr<unsigned char[]> uBuffer;
+ std::unique_ptr<unsigned char[]> uBuffer; // NOLINT
const rawspeed::ByteStream bs(buf, 0, buf.getSize());
for (auto _ : state) {
DeflateDecompressor d(bs, mRaw, predictor, BPS::value);
- d.decode(&uBuffer, mRaw->dim.x, mRaw->dim.y, 0, 0);
+ d.decode(&uBuffer, mRaw->dim.x, mRaw->dim.y, mRaw->dim.x, mRaw->dim.y, 0,
+ 0);
}
state.SetComplexityN(dim.area());
diff --git a/src/external/rawspeed/bench/librawspeed/interpolators/Cr2sRawInterpolatorBenchmark.cpp b/src/external/rawspeed/bench/librawspeed/interpolators/Cr2sRawInterpolatorBenchmark.cpp
index 74fbe1ffd..afef1354c 100644
--- a/src/external/rawspeed/bench/librawspeed/interpolators/Cr2sRawInterpolatorBenchmark.cpp
+++ b/src/external/rawspeed/bench/librawspeed/interpolators/Cr2sRawInterpolatorBenchmark.cpp
@@ -75,4 +75,4 @@ static constexpr const iPoint2D S420(2, 2);
BENCHMARK_TEMPLATE(BM_Cr2sRawInterpolator, S420, v<1>)->Apply(CustomArguments);
BENCHMARK_TEMPLATE(BM_Cr2sRawInterpolator, S420, v<2>)->Apply(CustomArguments);
-BENCHMARK_MAIN()
+BENCHMARK_MAIN();
diff --git a/src/external/rawspeed/bench/librawspeed/io/BitStreamBenchmark.cpp b/src/external/rawspeed/bench/librawspeed/io/BitStreamBenchmark.cpp
index 9d47475fd..4919cd5b5 100644
--- a/src/external/rawspeed/bench/librawspeed/io/BitStreamBenchmark.cpp
+++ b/src/external/rawspeed/bench/librawspeed/io/BitStreamBenchmark.cpp
@@ -130,8 +130,10 @@ void registerPump(const char* byteOrder, const char* pumpName) {
}
}
-#define REG_PUMP_2(BO, PUMP) registerPump<BO, PUMP>(#BO, #PUMP);
-#define REGISTER_PUMP(PUMP) REG_PUMP_2(Big, PUMP) REG_PUMP_2(Little, PUMP)
+#define REG_PUMP_2(BO, PUMP) registerPump<BO, PUMP>(#BO, #PUMP)
+#define REGISTER_PUMP(PUMP) \
+ REG_PUMP_2(Big, PUMP); \
+ REG_PUMP_2(Little, PUMP)
int main(int argc, char** argv) {
REGISTER_PUMP(BitPumpLSB);
diff --git a/src/external/rawspeed/bench/librawspeed/metadata/CMakeLists.txt b/src/external/rawspeed/bench/librawspeed/metadata/CMakeLists.txt
new file mode 100644
index 000000000..a6c9ab0e7
--- /dev/null
+++ b/src/external/rawspeed/bench/librawspeed/metadata/CMakeLists.txt
@@ -0,0 +1,11 @@
+if(NOT HAVE_PUGIXML)
+ return()
+endif()
+
+FILE(GLOB RAWSPEED_BENCHS_SOURCES
+ "CameraMetaDataBenchmark.cpp"
+)
+
+foreach(IN ${RAWSPEED_BENCHS_SOURCES})
+ add_rs_bench(${IN})
+endforeach()
diff --git a/src/external/rawspeed/bench/librawspeed/metadata/CameraMetaDataBenchmark.cpp b/src/external/rawspeed/bench/librawspeed/metadata/CameraMetaDataBenchmark.cpp
new file mode 100644
index 000000000..bffd188cf
--- /dev/null
+++ b/src/external/rawspeed/bench/librawspeed/metadata/CameraMetaDataBenchmark.cpp
@@ -0,0 +1,58 @@
+/*
+ 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 "rawspeedconfig.h" // for HAVE_PUGIXML
+#include "metadata/CameraMetaData.h" // for CameraMetaData
+#include <benchmark/benchmark.h> // for Benchmark, State, BENCHMARK_MAIN
+#include <pugixml.hpp> // for xml_document
+
+#ifndef HAVE_PUGIXML
+#error This benchmark requires to be built with pugixml being present.
+#endif
+
+static constexpr const char* const CAMERASXML =
+ CMAKE_SOURCE_DIR "/data/cameras.xml";
+
+static void BM_pugixml_load_cameras_xml(benchmark::State& state) {
+ for (auto _ : state) {
+ pugi::xml_document doc;
+
+#if defined(__unix__) || defined(__APPLE__)
+ pugi::xml_parse_result result = doc.load_file(CAMERASXML);
+#else
+ pugi::xml_parse_result result =
+ doc.load_file(pugi::as_wide(CAMERASXML).c_str());
+#endif
+
+ benchmark::DoNotOptimize(doc);
+ benchmark::DoNotOptimize(result);
+ }
+}
+BENCHMARK(BM_pugixml_load_cameras_xml)->Unit(benchmark::kMicrosecond);
+
+static void BM_CameraMetaData(benchmark::State& state) {
+ for (auto _ : state) {
+ rawspeed::CameraMetaData metadata(CAMERASXML);
+ benchmark::DoNotOptimize(metadata);
+ }
+}
+BENCHMARK(BM_CameraMetaData)->Unit(benchmark::kMicrosecond);
+
+BENCHMARK_MAIN();
diff --git a/src/external/rawspeed/cmake/Modules/CheckZLIB.cmake b/src/external/rawspeed/cmake/Modules/CheckZLIB.cmake
index 413b550ca..97d70cef8 100644
--- a/src/external/rawspeed/cmake/Modules/CheckZLIB.cmake
+++ b/src/external/rawspeed/cmake/Modules/CheckZLIB.cmake
@@ -3,6 +3,8 @@ include(CheckTypeSize)
include(CheckPrototypeDefinition)
include(CheckCXXSymbolExists)
+enable_language(C)
+
set(CMAKE_REQUIRED_INCLUDES_SAVE "${CMAKE_REQUIRED_INCLUDES}")
set(CMAKE_EXTRA_INCLUDE_FILES_SAVE "${CMAKE_EXTRA_INCLUDE_FILES}")
set(CMAKE_REQUIRED_LIBRARIES_SAVE "${CMAKE_REQUIRED_LIBRARIES}")
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMAr.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMAr.cmake
index aca7db536..4f5a90c20 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMAr.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMAr.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMAR_EXECUTABLE NAMES llvm-ar llvm-ar-6.0 llvm-ar-5.0 llvm-ar-4.0)
+find_program(LLVMAR_EXECUTABLE NAMES llvm-ar llvm-ar-7 llvm-ar-6.0 llvm-ar-5.0 llvm-ar-4.0 llvm-ar-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMAr
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMCXXFilt.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMCXXFilt.cmake
index 4cc093f09..2381d8df4 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMCXXFilt.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMCXXFilt.cmake
@@ -1,5 +1,5 @@
find_program(LLVMCXXFilt_EXECUTABLE
- NAMES llvm-cxxfilt llvm-cxxfilt-6.0 llvm-cxxfilt-5.0 llvm-cxxfilt-4.0
+ NAMES llvm-cxxfilt llvm-cxxfilt-7 llvm-cxxfilt-6.0 llvm-cxxfilt-5.0 llvm-cxxfilt-4.0 llvm-cxxfilt-3.9
DOC "The llvm-cxxfilt executable"
)
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMClangTidy.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMClangTidy.cmake
index 019b20c3b..3f3fb7f34 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMClangTidy.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMClangTidy.cmake
@@ -1,4 +1,4 @@
-find_program(CLANGTIDY_PATH NAMES clang-tidy clang-tidy-6.0)
+find_program(CLANGTIDY_PATH NAMES clang-tidy clang-tidy-7 clang-tidy-6.0 clang-tidy-5.0 clang-tidy-4.0 clang-tidy-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMClangTidy
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMCov.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMCov.cmake
index f8104959e..594c79a57 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMCov.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMCov.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMCOV_PATH NAMES llvm-cov)
+find_program(LLVMCOV_PATH NAMES llvm-cov llvm-cov-7 llvm-cov-6.0 llvm-cov-5.0 llvm-cov-4.0 llvm-cov-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMCov
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMLLD.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMLLD.cmake
index 6e8574dfd..8016089e9 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMLLD.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMLLD.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMLLD_EXECUTABLE NAMES ld.lld lld lld-6.0 lld-5.0)
+find_program(LLVMLLD_EXECUTABLE NAMES ld.lld lld lld-7 lld-6.0 lld-5.0 lld-4.0 lld-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMLLD
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMNm.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMNm.cmake
index 2872424e0..f92c4cbe5 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMNm.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMNm.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMNM_EXECUTABLE NAMES llvm-nm llvm-nm-6.0 llvm-nm-5.0 llvm-nm-4.0)
+find_program(LLVMNM_EXECUTABLE NAMES llvm-nm llvm-nm-7 llvm-nm-6.0 llvm-nm-5.0 llvm-nm-4.0 llvm-nm-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMNm
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMObjCopy.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMObjCopy.cmake
index 1eab8fd4e..f8c65de44 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMObjCopy.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMObjCopy.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMOBJCOPY_EXECUTABLE NAMES llvm-objcopy llvm-objcopy-6.0)
+find_program(LLVMOBJCOPY_EXECUTABLE NAMES llvm-objcopy llvm-objcopy-7 llvm-objcopy-6.0 llvm-objcopy-5.0 llvm-objcopy-4.0 llvm-objcopy-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMObjCopy
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMObjDump.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMObjDump.cmake
index 59abf7f25..2810ac002 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMObjDump.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMObjDump.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMOBJDUMP_EXECUTABLE NAMES llvm-objdump llvm-objdump-6.0 llvm-objdump-5.0 llvm-objdump-4.0)
+find_program(LLVMOBJDUMP_EXECUTABLE NAMES llvm-objdump llvm-objdump-7 llvm-objdump-6.0 llvm-objdump-5.0 llvm-objdump-4.0 llvm-objdump-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMObjDump
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMProfData.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMProfData.cmake
index 72ca5a861..b92b9420e 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMProfData.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMProfData.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMPROFDATA_PATH NAMES llvm-profdata)
+find_program(LLVMPROFDATA_PATH NAMES llvm-profdata llvm-profdata-7 llvm-profdata-6.0 llvm-profdata-5.0 llvm-profdata-4.0 llvm-profdata-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMProfData
diff --git a/src/external/rawspeed/cmake/Modules/FindLLVMRanLib.cmake b/src/external/rawspeed/cmake/Modules/FindLLVMRanLib.cmake
index 5db031194..860917a18 100644
--- a/src/external/rawspeed/cmake/Modules/FindLLVMRanLib.cmake
+++ b/src/external/rawspeed/cmake/Modules/FindLLVMRanLib.cmake
@@ -1,4 +1,4 @@
-find_program(LLVMRANLIB_EXECUTABLE NAMES llvm-ranlib llvm-ranlib-6.0 llvm-ranlib-5.0 llvm-ranlib-4.0)
+find_program(LLVMRANLIB_EXECUTABLE NAMES llvm-ranlib llvm-ranlib-7 llvm-ranlib-6.0 llvm-ranlib-5.0 llvm-ranlib-4.0 llvm-ranlib-3.9)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVMRanLib
diff --git a/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake b/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake
index 15d4d004e..7fa38528c 100644
--- a/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake
+++ b/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake
@@ -1,7 +1,3 @@
-cmake_minimum_required(VERSION 3.0)
-
-project(googlebenchmark NONE)
-
# Download and unpack googlebenchmark at configure time
configure_file(${RAWSPEED_SOURCE_DIR}/cmake/Modules/GoogleBenchmark.cmake.in ${CMAKE_BINARY_DIR}/googlebenchmark/CMakeLists.txt @ONLY)
@@ -44,9 +40,11 @@ set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_SAVE "${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
unset(CMAKE_CXX_CLANG_TIDY)
unset(CMAKE_CXX_INCLUDE_WHAT_YOU_USE)
+include(${CMAKE_BINARY_DIR}/googlebenchmark/googlebenchmark-paths.cmake)
+
# Add googlebenchmark directly to our build. This defines the benchmark target.
-add_subdirectory(${CMAKE_BINARY_DIR}/googlebenchmark/googlebenchmark-src
- ${CMAKE_BINARY_DIR}/googlebenchmark/googlebenchmark-build
+add_subdirectory(${GOOGLEBENCHMARK_SOURCE_DIR}
+ ${GOOGLEBENCHMARK_BINARY_DIR}
EXCLUDE_FROM_ALL)
set_target_properties(benchmark PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:benchmark,INTERFACE_INCLUDE_DIRECTORIES>)
diff --git a/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake.in b/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake.in
index ee18edc2c..38c25dcc8 100644
--- a/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake.in
+++ b/src/external/rawspeed/cmake/Modules/GoogleBenchmark.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.4.0)
project(googlebenchmark-download NONE)
@@ -17,11 +17,9 @@ if(EXISTS "${GOOGLEBENCHMARK_PATH}" AND IS_DIRECTORY "${GOOGLEBENCHMARK_PATH}" A
ExternalProject_Add(
googlebenchmark
- URL "${GOOGLEBENCHMARK_PATH}"
PREFIX "${CMAKE_BINARY_DIR}/googlebenchmark"
- SOURCE_DIR "${CMAKE_BINARY_DIR}/googlebenchmark-src"
+ SOURCE_DIR "${GOOGLEBENCHMARK_PATH}" # use existing src dir.
BINARY_DIR "${CMAKE_BINARY_DIR}/googlebenchmark-build"
- # PATCH_COMMAND patch -p1 -i "@rawspeed_SOURCE_DIR@/cmake/Modules/GoogleBenchmark-fixes.patch"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
@@ -34,12 +32,11 @@ else()
message(WARNING "Did not find GOOGLEBENCHMARK sources! Fetching from web...")
ExternalProject_Add(
googlebenchmark
- URL https://github.com/google/benchmark/archive/v1.3.0.tar.gz
- URL_HASH SHA512=272775e4dbd0ecc65a2a3a64f24e79682b630929dea3af47349329ac8b796341f1197458a67c9aac0e514857ebe7cbc191d18f6fd2c0aea3242562e69d8a6849
+ URL https://github.com/google/benchmark/archive/v1.4.1.tar.gz
+ URL_HASH SHA512=e9d71b4679cb4e4d755f7bb4101e131b37e209b6aebd0853e0c63eb11c42b75faa5da4ff8c265149808a475f3a1cfb140c5b49f877acfda908a4bb7add983aae
PREFIX "${CMAKE_BINARY_DIR}/googlebenchmark"
SOURCE_DIR "${CMAKE_BINARY_DIR}/googlebenchmark-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googlebenchmark-build"
- # PATCH_COMMAND patch -p1 -i "@rawspeed_SOURCE_DIR@/cmake/Modules/GoogleBenchmark-fixes.patch"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
@@ -47,3 +44,9 @@ else()
)
endif()
endif()
+
+ExternalProject_Get_Property(googlebenchmark SOURCE_DIR BINARY_DIR)
+file(WRITE googlebenchmark-paths.cmake
+"set(GOOGLEBENCHMARK_SOURCE_DIR \"${SOURCE_DIR}\")
+set(GOOGLEBENCHMARK_BINARY_DIR \"${BINARY_DIR}\")
+")
diff --git a/src/external/rawspeed/cmake/Modules/GoogleTest.cmake b/src/external/rawspeed/cmake/Modules/GoogleTest.cmake
index 2676db6e9..7839625c8 100644
--- a/src/external/rawspeed/cmake/Modules/GoogleTest.cmake
+++ b/src/external/rawspeed/cmake/Modules/GoogleTest.cmake
@@ -1,7 +1,3 @@
-cmake_minimum_required(VERSION 3.0)
-
-project(googletest NONE)
-
# Download and unpack googletest at configure time
configure_file(${RAWSPEED_SOURCE_DIR}/cmake/Modules/GoogleTest.cmake.in ${CMAKE_BINARY_DIR}/googletest/CMakeLists.txt @ONLY)
@@ -49,10 +45,12 @@ set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_SAVE "${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
unset(CMAKE_CXX_CLANG_TIDY)
unset(CMAKE_CXX_INCLUDE_WHAT_YOU_USE)
+include(${CMAKE_BINARY_DIR}/googletest/googletest-paths.cmake)
+
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
-add_subdirectory(${CMAKE_BINARY_DIR}/googletest/googletest-src
- ${CMAKE_BINARY_DIR}/googletest/googletest-build
+add_subdirectory(${GOOGLETEST_SOURCE_DIR}
+ ${GOOGLETEST_BINARY_DIR}
EXCLUDE_FROM_ALL)
set_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest,INTERFACE_INCLUDE_DIRECTORIES>)
diff --git a/src/external/rawspeed/cmake/Modules/GoogleTest.cmake.in b/src/external/rawspeed/cmake/Modules/GoogleTest.cmake.in
index ca876c4e9..c463accbb 100644
--- a/src/external/rawspeed/cmake/Modules/GoogleTest.cmake.in
+++ b/src/external/rawspeed/cmake/Modules/GoogleTest.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.4.0)
project(googletest-download NONE)
@@ -20,9 +20,8 @@ if(EXISTS "${GOOGLETEST_PATH}" AND IS_DIRECTORY "${GOOGLETEST_PATH}"
ExternalProject_Add(
googletest
- URL "${GOOGLETEST_PATH}"
PREFIX "${CMAKE_BINARY_DIR}/googletest"
- SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
+ SOURCE_DIR "${GOOGLETEST_PATH}" # use existing src dir.
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@@ -36,8 +35,8 @@ else()
message(WARNING "Did not find Google Test sources! Fetching from web...")
ExternalProject_Add(
googletest
- URL https://github.com/google/googletest/archive/release-1.8.0.tar.gz
- URL_HASH SHA512=1dbece324473e53a83a60601b02c92c089f5d314761351974e097b2cf4d24af4296f9eb8653b6b03b1e363d9c5f793897acae1f0c7ac40149216035c4d395d9d
+ URL https://github.com/google/googletest/archive/release-1.8.1.tar.gz
+ URL_HASH SHA512=e6283c667558e1fd6e49fa96e52af0e415a3c8037afe1d28b7ff1ec4c2ef8f49beb70a9327b7fc77eb4052a58c4ccad8b5260ec90e4bceeac7a46ff59c4369d7
PREFIX "${CMAKE_BINARY_DIR}/googletest"
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
@@ -48,3 +47,9 @@ else()
)
endif()
endif()
+
+ExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR)
+file(WRITE googletest-paths.cmake
+"set(GOOGLETEST_SOURCE_DIR \"${SOURCE_DIR}\")
+set(GOOGLETEST_BINARY_DIR \"${BINARY_DIR}\")
+")
diff --git a/src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake b/src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake
new file mode 100644
index 000000000..7465f8fcb
--- /dev/null
+++ b/src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake
@@ -0,0 +1,71 @@
+# Download and unpack LLVM OpenMP runtime library at configure time
+configure_file(${RAWSPEED_SOURCE_DIR}/cmake/Modules/LLVMOpenMP.cmake.in ${CMAKE_BINARY_DIR}/llvm-openmp/CMakeLists.txt @ONLY)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
+ -DALLOW_DOWNLOADING_LLVMOPENMP=${ALLOW_DOWNLOADING_LLVMOPENMP} -DLLVMOPENMP_PATH:PATH=${LLVMOPENMP_PATH} .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/llvm-openmp
+)
+
+if(result)
+ message(FATAL_ERROR "CMake step for LLVM OpenMP runtime library failed: ${result}")
+endif()
+
+execute_process(
+ COMMAND ${CMAKE_COMMAND} --build .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/llvm-openmp
+)
+
+if(result)
+ message(FATAL_ERROR "Build step for LLVM OpenMP runtime library failed: ${result}")
+endif()
+
+# We are building it separately from the LLVM itself.
+set(OPENMP_STANDALONE_BUILD ON CACHE BOOL "" FORCE)
+
+# let's insist on static library.
+set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
+set(LIBOMP_ENABLE_SHARED OFF CACHE BOOL "" FORCE)
+
+set(CMAKE_C_FLAGS_SAVE "${CMAKE_C_FLAGS}")
+set(CMAKE_CXX_FLAGS_SAVE "${CMAKE_CXX_FLAGS}")
+
+set(CMAKE_C_FLAGS_SANITIZE_SAVE "${CMAKE_C_FLAGS_SANITIZE}")
+set(CMAKE_CXX_FLAGS_SANITIZE_SAVE "${CMAKE_CXX_FLAGS_SANITIZE}")
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
+
+set(ubsan "-fsanitize-recover=undefined")
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set(ubsan "${ubsan} -fsanitize-recover=integer")
+endif()
+
+SET(CMAKE_CXX_FLAGS_SANITIZE "${CMAKE_CXX_FLAGS_SANITIZE} ${ubsan}")
+SET(CMAKE_C_FLAGS_SANITIZE "${CMAKE_C_FLAGS_SANITIZE} ${ubsan}")
+
+set(CMAKE_CXX_CLANG_TIDY_SAVE "${CMAKE_CXX_CLANG_TIDY}")
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_SAVE "${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
+
+unset(CMAKE_CXX_CLANG_TIDY)
+unset(CMAKE_CXX_INCLUDE_WHAT_YOU_USE)
+
+include(${CMAKE_BINARY_DIR}/llvm-openmp/llvm-openmp-paths.cmake)
+
+# Add llvm openmp directly to our build. This defines the omp target.
+add_subdirectory(${LLVMOPENMP_SOURCE_DIR}
+ ${LLVMOPENMP_BINARY_DIR}
+ EXCLUDE_FROM_ALL)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_SAVE}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_SAVE}")
+
+set(CMAKE_C_FLAGS_SANITIZE "${CMAKE_C_FLAGS_SANITIZE_SAVE}" CACHE STRING "Flags used by the C++ compiler during sanitized (ASAN+UBSAN) builds." FORCE )
+set(CMAKE_CXX_FLAGS_SANITIZE "${CMAKE_CXX_FLAGS_SANITIZE_SAVE}" CACHE STRING "Flags used by the C++ compiler during sanitized (ASAN+UBSAN) builds." FORCE )
+MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_SANITIZE
+ CMAKE_C_FLAGS_SANITIZE )
+
+set(CMAKE_CXX_CLANG_TIDY "${CMAKE_CXX_CLANG_TIDY_SAVE}")
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${CMAKE_CXX_INCLUDE_WHAT_YOU_USE_SAVE}")
diff --git a/src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake.in b/src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake.in
new file mode 100644
index 000000000..e2f7c9334
--- /dev/null
+++ b/src/external/rawspeed/cmake/Modules/LLVMOpenMP.cmake.in
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 3.4.0)
+
+project(llvm-openmp-download NONE)
+
+# Enable ExternalProject CMake module
+include(ExternalProject)
+
+option(ALLOW_DOWNLOADING_LLVMOPENMP "If LLVM OpenMP runtime library src tree is not found in location specified by LLVMOPENMP_PATH, do fetch the archive from internet" OFF)
+set(LLVMOPENMP_PATH "/usr/src/openmp" CACHE PATH "Path to the LLVM OpenMP runtime library root tree.")
+
+# Download and install LLVM OpenMP runtime library
+
+message(STATUS "Looking for LLVM OpenMP runtime library sources")
+message(STATUS "Looking for LLVM OpenMP runtime library sources in ${LLVMOPENMP_PATH}")
+if(EXISTS "${LLVMOPENMP_PATH}" AND IS_DIRECTORY "${LLVMOPENMP_PATH}" AND EXISTS "${LLVMOPENMP_PATH}/CMakeLists.txt")
+ message(STATUS "Found LLVM OpenMP runtime library in ${LLVMOPENMP_PATH}")
+
+ ExternalProject_Add(
+ llvm-openmp
+ PREFIX "${CMAKE_BINARY_DIR}/llvm-openmp"
+ SOURCE_DIR "${LLVMOPENMP_PATH}" # use existing src dir.
+ BINARY_DIR "${CMAKE_BINARY_DIR}/llvm-openmp-build"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+ )
+else()
+ if(NOT ALLOW_DOWNLOADING_LLVMOPENMP)
+ message(SEND_ERROR "Did not find LLVM OpenMP runtime library sources! Either pass correct path in LLVMOPENMP_PATH, or enable ALLOW_DOWNLOADING_LLVMOPENMP, or disable USE_BUNDLED_LLVMOPENMP, or disable WITH_OPENMP.")
+ else()
+ message(WARNING "Did not find LLVM OpenMP runtime library sources! Fetching from web...")
+ ExternalProject_Add(
+ llvm-openmp
+ URL https://releases.llvm.org/7.0.0/openmp-7.0.0.src.tar.xz
+ URL_HASH SHA512=bda383d62c822db41504d7774974809cd2af042b03a0b4ca450cc1478c5977682f5c646734801c1b7a16233141d62359c17e87e1435c48a222e159a8763f8857
+ PREFIX "${CMAKE_BINARY_DIR}/llvm-openmp"
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/llvm-openmp-src"
+ BINARY_DIR "${CMAKE_BINARY_DIR}/llvm-openmp-build"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+ )
+ endif()
+endif()
+
+ExternalProject_Get_Property(llvm-openmp SOURCE_DIR BINARY_DIR)
+file(WRITE llvm-openmp-paths.cmake
+"set(LLVMOPENMP_SOURCE_DIR \"${SOURCE_DIR}\")
+set(LLVMOPENMP_BINARY_DIR \"${BINARY_DIR}\")
+")
diff --git a/src/external/rawspeed/cmake/Modules/Pugixml.cmake b/src/external/rawspeed/cmake/Modules/Pugixml.cmake
index 752ceb7d6..78454d7a8 100644
--- a/src/external/rawspeed/cmake/Modules/Pugixml.cmake
+++ b/src/external/rawspeed/cmake/Modules/Pugixml.cmake
@@ -1,7 +1,3 @@
-cmake_minimum_required(VERSION 3.0)
-
-project(pugixml NONE)
-
# Download and unpack pugixml at configure time
configure_file(${RAWSPEED_SOURCE_DIR}/cmake/Modules/Pugixml.cmake.in ${CMAKE_BINARY_DIR}/pugixml/CMakeLists.txt @ONLY)
@@ -43,10 +39,12 @@ set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_SAVE "${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
unset(CMAKE_CXX_CLANG_TIDY)
unset(CMAKE_CXX_INCLUDE_WHAT_YOU_USE)
+include(${CMAKE_BINARY_DIR}/pugixml/pugixml-paths.cmake)
+
# Add pugixml directly to our build. This defines
# the gtest and gtest_main targets.
-add_subdirectory(${CMAKE_BINARY_DIR}/pugixml/pugixml-src
- ${CMAKE_BINARY_DIR}/pugixml/pugixml-build)
+add_subdirectory(${PUGIXML_SOURCE_DIR}
+ ${PUGIXML_BINARY_DIR})
set_target_properties(pugixml PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:pugixml,INTERFACE_INCLUDE_DIRECTORIES>)
diff --git a/src/external/rawspeed/cmake/Modules/Pugixml.cmake.in b/src/external/rawspeed/cmake/Modules/Pugixml.cmake.in
index 536f0e258..a6f3f2a4b 100644
--- a/src/external/rawspeed/cmake/Modules/Pugixml.cmake.in
+++ b/src/external/rawspeed/cmake/Modules/Pugixml.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.4.0)
project(pugixml-download NONE)
@@ -17,9 +17,8 @@ if(EXISTS "${PUGIXML_PATH}" AND IS_DIRECTORY "${PUGIXML_PATH}" AND EXISTS "${PUG
ExternalProject_Add(
pugixml
- URL "${PUGIXML_PATH}"
PREFIX "${CMAKE_BINARY_DIR}/pugixml"
- SOURCE_DIR "${CMAKE_BINARY_DIR}/pugixml-src"
+ SOURCE_DIR "${PUGIXML_PATH}" # use existing src dir.
BINARY_DIR "${CMAKE_BINARY_DIR}/pugixml-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@@ -33,8 +32,8 @@ else()
message(WARNING "Did not find pugixml sources! Fetching from web...")
ExternalProject_Add(
pugixml
- URL https://github.com/zeux/pugixml/releases/download/v1.8.1/pugixml-1.8.1.tar.gz
- URL_HASH SHA512=1aec6f8cd0c385b66e848020d94d331db788c78523f72d145726738433a784b518084ec45a6eeffb0a6585bcf2759d09ad1e3d304d15d99068d43dbfd6db9d31
+ URL https://github.com/zeux/pugixml/releases/download/v1.9/pugixml-1.9.tar.gz
+ URL_HASH SHA512=853a9d985aae537391c6524d5413ef4de237d99d96cc58ea7fe7152f786df1e408cdacd2e4387697e23c3e67cdc1d42b29de554501309eae16d86edd0e24785f
PREFIX "${CMAKE_BINARY_DIR}/pugixml"
SOURCE_DIR "${CMAKE_BINARY_DIR}/pugixml-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/pugixml-build"
@@ -45,3 +44,9 @@ else()
)
endif()
endif()
+
+ExternalProject_Get_Property(pugixml SOURCE_DIR BINARY_DIR)
+file(WRITE pugixml-paths.cmake
+"set(PUGIXML_SOURCE_DIR \"${SOURCE_DIR}\")
+set(PUGIXML_BINARY_DIR \"${BINARY_DIR}\")
+")
diff --git a/src/external/rawspeed/cmake/Modules/Zlib.cmake b/src/external/rawspeed/cmake/Modules/Zlib.cmake
index 31a4d024f..df114c5bf 100644
--- a/src/external/rawspeed/cmake/Modules/Zlib.cmake
+++ b/src/external/rawspeed/cmake/Modules/Zlib.cmake
@@ -1,7 +1,3 @@
-cmake_minimum_required(VERSION 3.0)
-
-project(zlib NONE)
-
# Download and unpack zlib at configure time
configure_file(${RAWSPEED_SOURCE_DIR}/cmake/Modules/Zlib.cmake.in ${CMAKE_BINARY_DIR}/zlib/CMakeLists.txt @ONLY)
@@ -40,15 +36,17 @@ set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_SAVE "${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}")
unset(CMAKE_CXX_CLANG_TIDY)
unset(CMAKE_CXX_INCLUDE_WHAT_YOU_USE)
+include(${CMAKE_BINARY_DIR}/zlib/zlib-paths.cmake)
+
# XXX make sure that zlib is using it's own headers
# see https://github.com/madler/zlib/issues/218
-include_directories(BEFORE ${CMAKE_BINARY_DIR}/zlib/zlib-src)
-include_directories(BEFORE ${CMAKE_BINARY_DIR}/zlib/zlib-build)
+include_directories(BEFORE SYSTEM ${CMAKE_BINARY_DIR}/zlib/zlib-src)
+include_directories(BEFORE SYSTEM ${CMAKE_BINARY_DIR}/zlib/zlib-build)
# Add zlib directly to our build. This defines
# the gtest and gtest_main targets.
-add_subdirectory(${CMAKE_BINARY_DIR}/zlib/zlib-src
- ${CMAKE_BINARY_DIR}/zlib/zlib-build)
+add_subdirectory(${ZLIB_SOURCE_DIR}
+ ${ZLIB_BINARY_DIR})
set(_zlib_lib zlib) # shared
set(_zlib_lib zlibstatic) # static
diff --git a/src/external/rawspeed/cmake/Modules/Zlib.cmake.in b/src/external/rawspeed/cmake/Modules/Zlib.cmake.in
index 1f4a7a8a9..8a26de4e9 100644
--- a/src/external/rawspeed/cmake/Modules/Zlib.cmake.in
+++ b/src/external/rawspeed/cmake/Modules/Zlib.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.4.0)
project(zlib-download NONE)
@@ -17,9 +17,8 @@ if(EXISTS "${ZLIB_PATH}" AND IS_DIRECTORY "${ZLIB_PATH}" AND EXISTS "${ZLIB_PATH
ExternalProject_Add(
zlib
- URL "${ZLIB_PATH}"
PREFIX "${CMAKE_BINARY_DIR}/zlib"
- SOURCE_DIR "${CMAKE_BINARY_DIR}/zlib-src"
+ SOURCE_DIR "${ZLIB_PATH}" # use existing src dir.
BINARY_DIR "${CMAKE_BINARY_DIR}/zlib-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@@ -45,3 +44,9 @@ else()
)
endif()
endif()
+
+ExternalProject_Get_Property(zlib SOURCE_DIR BINARY_DIR)
+file(WRITE zlib-paths.cmake
+"set(ZLIB_SOURCE_DIR \"${SOURCE_DIR}\")
+set(ZLIB_BINARY_DIR \"${BINARY_DIR}\")
+")
diff --git a/src/external/rawspeed/cmake/OpenMP.cmake b/src/external/rawspeed/cmake/OpenMP.cmake
deleted file mode 100644
index e9902f603..000000000
--- a/src/external/rawspeed/cmake/OpenMP.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-if(WITH_OPENMP)
- message(STATUS "Looking for OpenMP")
- find_package(OpenMP)
- if(OPENMP_FOUND)
- message(STATUS "Looking for OpenMP - found")
- set(HAVE_OPENMP 1)
-
- if(NOT TARGET OpenMP::OpenMP)
- add_library(OpenMP::OpenMP INTERFACE IMPORTED)
- set_property(TARGET OpenMP::OpenMP PROPERTY INTERFACE_COMPILE_OPTIONS "${OpenMP_CXX_FLAGS}")
- set_property(TARGET OpenMP::OpenMP PROPERTY INTERFACE_LINK_LIBRARIES "${OpenMP_CXX_FLAGS}")
- endif()
-
- set_package_properties(OpenMP PROPERTIES
- TYPE OPTIONAL
- PURPOSE "Used for parallelization of tools (NOT library!)")
- else()
- message(WARNING "Looking for OpenMP - failed. utilities will not use openmp-based parallelization")
- endif()
-else()
- message(STATUS "OpenMP is disabled, utilities will not use openmp-based parallelization")
-endif()
-add_feature_info("OpenMP-based utilities threading" HAVE_OPENMP "used for parallelization of utilities only, NOT library!")
diff --git a/src/external/rawspeed/cmake/compiler-flags.cmake b/src/external/rawspeed/cmake/compiler-flags.cmake
index a6cb2decc..9e51ab472 100644
--- a/src/external/rawspeed/cmake/compiler-flags.cmake
+++ b/src/external/rawspeed/cmake/compiler-flags.cmake
@@ -21,9 +21,7 @@ set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-# always debug info
-add_definitions(-g3)
-add_definitions(-ggdb3)
+include(debug-info)
if(CMAKE_BUILD_TYPE STREQUAL "RELEASE")
# want assertions in all but Release build type.
@@ -40,6 +38,10 @@ elseif(NOT (CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO" OR CMAKE_BUILD_TYPE STREQ
add_definitions(-D_GLIBCXX_SANITIZE_VECTOR)
endif()
+set(CMAKE_C_VISIBILITY_PRESET hidden)
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
IF(NOT APPLE)
set(linkerflags "-Wl,--as-needed")
ELSE()
@@ -63,12 +65,15 @@ MARK_AS_ADVANCED(
if(RAWSPEED_ENABLE_LTO)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
include(llvm-toolchain)
- set(lto_compile "-flto=thin")
+ set(lto_compile "-flto=thin -fforce-emit-vtables -fwhole-program-vtables -fstrict-vtable-pointers")
set(lto_link "-flto=thin -fuse-ld=\"${LLVMLLD_EXECUTABLE}\" ${LLVMLLD_INCREMENTAL_LDFLAGS}")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
include(gcc-toolchain)
set(lto_compile "-flto")
set(lto_link "-flto")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ set(lto_compile "-flto=thin -fstrict-vtable-pointers")
+ set(lto_link "-flto=thin")
endif()
set(CMAKE_C_FLAGS
diff --git a/src/external/rawspeed/cmake/compiler-versions.cmake b/src/external/rawspeed/cmake/compiler-versions.cmake
index c3458e905..f3d561d6e 100644
--- a/src/external/rawspeed/cmake/compiler-versions.cmake
+++ b/src/external/rawspeed/cmake/compiler-versions.cmake
@@ -1,4 +1,4 @@
-# want C++14 support.
+# want C++14 support, openmp 4.0 support.
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
message(FATAL_ERROR "GNU C compiler version ${CMAKE_C_COMPILER_VERSION} is too old. Need 5.0+")
@@ -8,26 +8,29 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_L
message(FATAL_ERROR "GNU C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is too old. Need 5.0+")
endif()
-if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 3.5)
- message(FATAL_ERROR "LLVM Clang C compiler version ${CMAKE_C_COMPILER_VERSION} is too old. Need 3.5+")
+if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9)
+ message(FATAL_ERROR "LLVM Clang C compiler version ${CMAKE_C_COMPILER_VERSION} is too old. Need 3.9+")
endif()
-if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
- message(FATAL_ERROR "LLVM Clang C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is too old. Need 3.5+")
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9)
+ message(FATAL_ERROR "LLVM Clang C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is too old. Need 3.9+")
endif()
-# if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
-# message(WARNING "Support for GNU C compiler version ${CMAKE_C_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 5.0+")
+
+# C++17 ?
+
+# if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 7)
+# message(WARNING "Support for GNU C compiler version ${CMAKE_C_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 7+")
# endif()
-# if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
-# message(WARNING "Support for GNU C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 5.0+")
+# if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7)
+# message(WARNING "Support for GNU C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 7+")
# endif()
-# if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 3.5)
-# message(WARNING "LLVM Clang C compiler version ${CMAKE_C_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 3.5+")
+# if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
+# message(WARNING "LLVM Clang C compiler version ${CMAKE_C_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 4.0+")
# endif()
-# if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
-# message(WARNING "LLVM Clang C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 3.5+")
+# if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
+# message(WARNING "LLVM Clang C++ compiler version ${CMAKE_CXX_COMPILER_VERSION} is soft-deprecated. Consider upgrading to 4.0+")
# endif()
diff --git a/src/external/rawspeed/cmake/debug-info.cmake b/src/external/rawspeed/cmake/debug-info.cmake
new file mode 100644
index 000000000..30651a477
--- /dev/null
+++ b/src/external/rawspeed/cmake/debug-info.cmake
@@ -0,0 +1,9 @@
+if(RAWSPEED_ENABLE_DEBUG_INFO)
+ # always debug info
+ add_definitions(-g3)
+ add_definitions(-ggdb3)
+elseif(NOT RAWSPEED_ENABLE_DEBUG_INFO)
+ add_definitions(-g0)
+else()
+ message(SEND_ERROR "RAWSPEED_ENABLE_DEBUG_INFO has unknown value: \"${RAWSPEED_ENABLE_DEBUG_INFO}\"")
+endif()
diff --git a/src/external/rawspeed/cmake/gcc-gcov.cmake b/src/external/rawspeed/cmake/gcc-gcov.cmake
index af4b8a1d9..13196240a 100644
--- a/src/external/rawspeed/cmake/gcc-gcov.cmake
+++ b/src/external/rawspeed/cmake/gcc-gcov.cmake
@@ -23,7 +23,7 @@ endif()
add_custom_target(
gcov
- COMMAND "${FIND_PATH}" "${CMAKE_BINARY_DIR}" -type f -name '*.gcno' -exec "${GCOV_PATH}" ${GCOV_OPTS} {} + > /dev/null
+ COMMAND "${FIND_PATH}" "${CMAKE_BINARY_DIR}" -type f -name '*.gcno' -exec "${GCOV_PATH}" ${GCOV_OPTS} {} \\\\; > /dev/null
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Running gcov tool on all the *.gcno files to produce *.gcov files"
USES_TERMINAL
diff --git a/src/external/rawspeed/cmake/iwyu.imp b/src/external/rawspeed/cmake/iwyu.imp
index 441812158..6a76176cb 100644
--- a/src/external/rawspeed/cmake/iwyu.imp
+++ b/src/external/rawspeed/cmake/iwyu.imp
@@ -2,6 +2,13 @@
{ include: ["<zconf.h>", "private", "<zlib.h>", "public"] },
{ include: ["<jconfig.h>", "private", "<jpeglib.h>", "public"] },
{ include: ["<jmorecfg.h>", "private", "<jpeglib.h>", "public"] },
+ { include: ["<bits/std_abs.h>", "private", "<cmath>", "public"] },
+ { include: ["<bits/stl_set.h>", "private", "<set>", "public"] },
+ { include: ["<bits/stdint-uintn.h>", "private", "<cstdint>", "public"] },
+ { include: ["<bits/exception.h>", "private", "<exception>", "public"] },
+ { include: ["<bits/types/clock_t.h>", "private", "<ctime>", "public"] },
+ { include: ["<bits/std_function.h>", "private", "<functional>", "public"] },
+ { include: ["<bits/stdint-intn.h>", "private", "<cstdint>", "public"] },
{ include: ["@<gtest/.*>", "private", "<gtest/gtest.h>", "public"] },
{ include: ["@<gmock/.*>", "private", "<gmock/gmock.h>", "public"] },
{ include: ["<ThreadSafetyAnalysis.h>", "private", "\"ThreadSafetyAnalysis.h\"", "public"] }
diff --git a/src/external/rawspeed/cmake/llvm-cov.cmake b/src/external/rawspeed/cmake/llvm-cov.cmake
index 7ec9b2f61..f54f5a6e8 100644
--- a/src/external/rawspeed/cmake/llvm-cov.cmake
+++ b/src/external/rawspeed/cmake/llvm-cov.cmake
@@ -14,7 +14,7 @@ find_package(Demangler REQUIRED)
add_custom_target(
coverage-show
DEPENDS rstest
- COMMAND "${LLVMCOV_PATH}" show -Xdemangler=$<TARGET_FILE:demangler> -instr-profile "${CMAKE_BINARY_DIR}/rawspeed.profdata" "$<TARGET_FILE:rstest>" -format html -output-dir "${CMAKE_BINARY_DIR}/coverage"
+ COMMAND "${LLVMCOV_PATH}" show -Xdemangler=$<TARGET_FILE:demangler> -instr-profile "${RAWSPEED_PROFDATA_FILE}" "$<TARGET_FILE:rstest>" -format html -output-dir "${CMAKE_BINARY_DIR}/coverage"
COMMAND "${CMAKE_COMMAND}" -E echo "Use $$ sensible-browser \"./coverage/index.html\" to view the coverage report."
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Running llvm-cov tool on the *.profdata file to generate HTML coverage report"
diff --git a/src/external/rawspeed/cmake/llvm-profdata.cmake b/src/external/rawspeed/cmake/llvm-profdata.cmake
index ecd4247ec..b9bae9e28 100644
--- a/src/external/rawspeed/cmake/llvm-profdata.cmake
+++ b/src/external/rawspeed/cmake/llvm-profdata.cmake
@@ -11,7 +11,7 @@ find_package(Find REQUIRED)
add_custom_target(
profdata
- COMMAND "${FIND_PATH}" "${CMAKE_BINARY_DIR}" -type f -name '*.profraw' -exec "${LLVMPROFDATA_PATH}" merge -o "${CMAKE_BINARY_DIR}/rawspeed.profdata" {} + > /dev/null
+ COMMAND "${FIND_PATH}" "${CMAKE_BINARY_DIR}" -type f -name '*.profraw' -exec "${LLVMPROFDATA_PATH}" merge -o "${RAWSPEED_PROFDATA_FILE}" {} + > /dev/null
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Running llvm-profdata tool on all the *.profraw files"
)
diff --git a/src/external/rawspeed/cmake/sample-based-testing.cmake b/src/external/rawspeed/cmake/sample-based-testing.cmake
index a1d29adb2..74b479ed8 100644
--- a/src/external/rawspeed/cmake/sample-based-testing.cmake
+++ b/src/external/rawspeed/cmake/sample-based-testing.cmake
@@ -1,22 +1,26 @@
message(STATUS "Looking for sample set for sample-based testing")
-message(STATUS "Looking for sample set in ${REFERENCE_SAMPLE_ARCHIVE}")
-if(NOT (EXISTS "${REFERENCE_SAMPLE_ARCHIVE}"
- AND EXISTS "${REFERENCE_SAMPLE_ARCHIVE}/filelist.sha1"
- AND EXISTS "${REFERENCE_SAMPLE_ARCHIVE}/timestamp.txt"))
- message(SEND_ERROR "Did not find sample set for sample-based testing! Either pass correct path in REFERENCE_SAMPLE_ARCHIVE, or disable ENABLE_SAMPLEBASED_TESTING.")
+message(STATUS "Looking for sample set in ${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}")
+if(NOT (EXISTS "${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}"
+ AND EXISTS "${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}/filelist.sha1"
+ AND EXISTS "${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}/timestamp.txt"))
+ message(SEND_ERROR "Did not find sample set for sample-based testing! Either pass correct path in RAWSPEED_REFERENCE_SAMPLE_ARCHIVE, or disable RAWSPEED_ENABLE_SAMPLE_BASED_TESTING.")
endif()
-message(STATUS "Found sample set in ${REFERENCE_SAMPLE_ARCHIVE}")
+message(STATUS "Found sample set in ${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}")
-file(STRINGS "${REFERENCE_SAMPLE_ARCHIVE}/filelist.sha1" _REFERENCE_SAMPLES ENCODING UTF-8)
+file(STRINGS "${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}/filelist.sha1" _REFERENCE_SAMPLES ENCODING UTF-8)
set(REFERENCE_SAMPLES)
set(REFERENCE_SAMPLE_HASHES)
foreach(STR ${_REFERENCE_SAMPLES})
- string(SUBSTRING "${STR}" 40 -1 SAMPLENAME)
- string(STRIP "${SAMPLENAME}" SAMPLENAME)
- set(SAMPLENAME "${REFERENCE_SAMPLE_ARCHIVE}/${SAMPLENAME}")
+ # There are two schemes:
+ # <hash><space><space><filename> <- read in text mode
+ # <hash><space><asterisk><filename> <- read in binary mode
+ # Which for our purpose means:
+ # <40 chars><char><char><filename> <- i.e. we just skip first 42 chars.
+ string(SUBSTRING "${STR}" 42 -1 SAMPLENAME)
+ set(SAMPLENAME "${RAWSPEED_REFERENCE_SAMPLE_ARCHIVE}/${SAMPLENAME}")
if(NOT EXISTS "${SAMPLENAME}")
message(SEND_ERROR "The sample \"${SAMPLENAME}\" does not exist!")
@@ -27,34 +31,43 @@ foreach(STR ${_REFERENCE_SAMPLES})
list(APPEND REFERENCE_SAMPLE_HASHES "${SAMPLENAME}.hash.failed")
endforeach()
+set(EXTRA_ENV "")
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
+ CMAKE_BUILD_TYPE STREQUAL "COVERAGE")
+ message(WARNING "Warning: sample-based-testing; clang instrumentation profile"
+ " does not work with threading! Will be passing "
+ "OMP_NUM_THREADS=1 environment variable.")
+ set(EXTRA_ENV "OMP_NUM_THREADS=1")
+endif()
+
add_custom_target(rstest-create)
add_custom_command(TARGET rstest-create
- COMMAND rstest -c ${REFERENCE_SAMPLES}
- WORKING_DIRECTORY "${REFERENCE_SAMPLE_ARCHIVE}"
+ COMMAND "${CMAKE_COMMAND}" -E env ${EXTRA_ENV} "$<TARGET_FILE:rstest>" -c ${REFERENCE_SAMPLES}
+ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
COMMENT "Running rstest on all the samples in the sample set to generate the missing hashes"
VERBATIM
USES_TERMINAL)
add_custom_target(rstest-recreate)
add_custom_command(TARGET rstest-recreate
- COMMAND rstest -c -f ${REFERENCE_SAMPLES}
- WORKING_DIRECTORY "${REFERENCE_SAMPLE_ARCHIVE}"
+ COMMAND "${CMAKE_COMMAND}" -E env ${EXTRA_ENV} "$<TARGET_FILE:rstest>" -c -f ${REFERENCE_SAMPLES}
+ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
COMMENT "Running rstest on all the samples in the sample set to [re]generate all the hashes"
VERBATIM
USES_TERMINAL)
add_custom_target(rstest-test) # hashes must exist beforehand
add_custom_command(TARGET rstest-test
- COMMAND rstest ${REFERENCE_SAMPLES}
- WORKING_DIRECTORY "${REFERENCE_SAMPLE_ARCHIVE}"
+ COMMAND "${CMAKE_COMMAND}" -E env ${EXTRA_ENV} "$<TARGET_FILE:rstest>" ${REFERENCE_SAMPLES}
+ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
COMMENT "Running rstest on all the samples in the sample set to check for regressions"
VERBATIM
USES_TERMINAL)
add_custom_target(rstest-check) # hashes should exist beforehand if you want to check for regressions
add_custom_command(TARGET rstest-check
- COMMAND rstest -f ${REFERENCE_SAMPLES}
- WORKING_DIRECTORY "${REFERENCE_SAMPLE_ARCHIVE}"
+ COMMAND "${CMAKE_COMMAND}" -E env ${EXTRA_ENV} "$<TARGET_FILE:rstest>" -f ${REFERENCE_SAMPLES}
+ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
COMMENT "Trying to decode all the samples in the sample set"
VERBATIM
USES_TERMINAL)
@@ -62,6 +75,6 @@ add_custom_command(TARGET rstest-check
add_custom_target(rstest-clean)
add_custom_command(TARGET rstest-clean
COMMAND "${CMAKE_COMMAND}" -E remove ${REFERENCE_SAMPLE_HASHES}
- WORKING_DIRECTORY "${REFERENCE_SAMPLE_ARCHIVE}"
+ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
COMMENT "Removing *.hash, *.hash.failed for the each sample in the set"
VERBATIM)
diff --git a/src/external/rawspeed/cmake/src-dependencies.cmake b/src/external/rawspeed/cmake/src-dependencies.cmake
index 7a3a471b6..2aee628f0 100644
--- a/src/external/rawspeed/cmake/src-dependencies.cmake
+++ b/src/external/rawspeed/cmake/src-dependencies.cmake
@@ -1,3 +1,5 @@
+include(FeatureSummary)
+
if(BUILD_TESTING)
# want GTEST_ADD_TESTS() macro. NOT THE ACTUAL MODULE!
include(GTEST_ADD_TESTS)
@@ -17,12 +19,13 @@ if(BUILD_BENCHMARKING)
add_dependencies(dependencies benchmark)
endif()
+unset(HAVE_PTHREAD)
if(WITH_PTHREADS)
message(STATUS "Looking for PThreads")
set(CMAKE_THREAD_PREFER_PTHREAD 1)
find_package(Threads)
if(NOT CMAKE_USE_PTHREADS_INIT)
- message(SEND_ERROR "Did not found POSIX Threads! Either make it find PThreads, or pass -DWITH_PTHREADS=OFF to disable threading.")
+ message(SEND_ERROR "Did not find POSIX Threads! Either make it find PThreads, or pass -DWITH_PTHREADS=OFF to disable threading.")
else()
message(STATUS "Looking for PThreads - found")
set(HAVE_PTHREAD 1)
@@ -30,21 +33,74 @@ if(WITH_PTHREADS)
set_package_properties(Threads PROPERTIES
TYPE RECOMMENDED
DESCRIPTION "POSIX Threads"
- PURPOSE "Used for parallelization of the library itself")
+ PURPOSE "Used for the main parallelization of the library")
endif()
else()
message(STATUS "PThread-based threading is disabled. Not searching for PThreads")
endif()
-add_feature_info("PThread-based library threading" HAVE_PTHREAD "used for parallelized image decoding")
+add_feature_info("PThread-based threading" HAVE_PTHREAD "used for parallelized image decoding")
+
+unset(HAVE_OPENMP)
+if(WITH_OPENMP)
+ if(NOT HAVE_PTHREAD)
+ message(SEND_ERROR "POSIX locking API is used, but the POSIX Threads "
+ "weren't found, thus can not enable OpenMP support. "
+ "Either make it find PThreads, or pass "
+ "-DWITH_OPENMP=OFF to disable OpenMP support.")
+ endif()
+
+ message(STATUS "Looking for OpenMP")
+ find_package(OpenMP)
+
+ if(NOT OPENMP_FOUND)
+ message(SEND_ERROR "Did not find OpenMP! Either make it find OpenMP, "
+ "or pass -DWITH_OPENMP=OFF to disable OpenMP support.")
+ else()
+ message(STATUS "Looking for OpenMP - found (system)")
+ endif()
+
+ # FIXME: OpenMP::OpenMP_CXX target, and ${OpenMP_CXX_LIBRARIES} were both
+ # added in cmake-3.9. Until then, this is correct:
+ if(NOT TARGET OpenMP::OpenMP_CXX)
+ add_library(OpenMP::OpenMP_CXX INTERFACE IMPORTED)
+ if(OpenMP_CXX_FLAGS)
+ set_property(TARGET OpenMP::OpenMP_CXX PROPERTY INTERFACE_COMPILE_OPTIONS ${OpenMP_CXX_FLAGS})
+ set_property(TARGET OpenMP::OpenMP_CXX PROPERTY INTERFACE_LINK_LIBRARIES ${OpenMP_CXX_FLAGS})
+ # Yes, both of them to the same value.
+ endif()
+ endif()
-include(OpenMP)
+ if(NOT USE_BUNDLED_LLVMOPENMP)
+ target_link_libraries(rawspeed PUBLIC OpenMP::OpenMP_CXX)
+ else()
+ include(LLVMOpenMP)
+
+ message(STATUS "Looking for OpenMP - found 'in-tree' runtime library")
+
+ add_dependencies(dependencies omp)
+ target_compile_options(rawspeed PUBLIC $<TARGET_PROPERTY:OpenMP::OpenMP_CXX,INTERFACE_COMPILE_OPTIONS>) # compile time only!
+ target_link_libraries(rawspeed PUBLIC omp) # newly built runtime library
+ endif()
+
+ set(HAVE_OPENMP 1)
+
+ set_package_properties(OpenMP PROPERTIES
+ TYPE RECOMMENDED
+ URL https://www.openmp.org/
+ DESCRIPTION "Open Multi-Processing"
+ PURPOSE "Marginally used for parallelization the library")
+else()
+ message(STATUS "OpenMP is disabled")
+endif()
+add_feature_info("OpenMP-based threading" HAVE_OPENMP "used for parallelized image decoding")
+unset(HAVE_PUGIXML)
if(WITH_PUGIXML)
message(STATUS "Looking for pugixml")
if(NOT USE_BUNDLED_PUGIXML)
find_package(Pugixml 1.2)
if(NOT Pugixml_FOUND)
- message(SEND_ERROR "Did not found Pugixml! Either make it find Pugixml, or pass -DUSE_BUNDLED_PUGIXML=ON to enable in-tree pugixml.")
+ message(SEND_ERROR "Did not find Pugixml! Either make it find Pugixml, or pass -DUSE_BUNDLED_PUGIXML=ON to enable in-tree pugixml.")
else()
message(STATUS "Looking for pugixml - found (system)")
endif()
@@ -79,6 +135,7 @@ else()
endif()
add_feature_info("XML reading" HAVE_PUGIXML "used for loading of data/cameras.xml")
+unset(HAVE_JPEG)
if(WITH_JPEG)
message(STATUS "Looking for JPEG")
find_package(JPEG)
@@ -107,6 +164,7 @@ else()
endif()
add_feature_info("Lossy JPEG decoding" HAVE_JPEG "used for DNG Lossy JPEG compression decoding")
+unset(HAVE_ZLIB)
if (WITH_ZLIB)
message(STATUS "Looking for ZLIB")
if(NOT USE_BUNDLED_ZLIB)
diff --git a/src/external/rawspeed/data/README.md b/src/external/rawspeed/data/README.md
index ca692fc35..edcccdf6b 100644
--- a/src/external/rawspeed/data/README.md
+++ b/src/external/rawspeed/data/README.md
@@ -1,6 +1,13 @@
# RawSpeed Camera Definition File
-The camera definition file is used for decoding images which don’t require any code changes. This enables us to add support for cameras which were not yet released when the code was written.
+The camera definition file is used to list the explicitly supported (or unsupported) cameras.
+
+WARNING: the format of that file is **not** stable.
+There is **no** backward (or forward) compatibility guarantees.
+Given RawSpeed code version `V`, only that very `cameras.xml` from that same
+version is guaranteed to work.
+`cameras.xml` from version `V+1` may not work.
+`cameras.xml` from version `V-1` may not work.
```xml
<Camera make="Panasonic" model="DMC-FZ45" mode="4:3" supported="yes" decoder_version="0">
diff --git a/src/external/rawspeed/data/cameras.xml b/src/external/rawspeed/data/cameras.xml
index 89e012a07..278ecc60d 100644
--- a/src/external/rawspeed/data/cameras.xml
+++ b/src/external/rawspeed/data/cameras.xml
@@ -716,6 +716,26 @@
<Horizontal y="0" height="40"/>
</BlackAreas>
</Camera>
+ <Camera make="Canon" model="Canon EOS 5D Mark IV" mode="sRaw1">
+ <ID make="Canon" model="EOS 5D Mark IV">Canon EOS 5D Mark IV</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="56032"/>
+ <!-- FIXME: iso50? -->
+ <Hints>
+ <Hint name="sraw_new" value=""/>
+ <Hint name="invert_sraw_wb" value=""/>
+ </Hints>
+ </Camera>
+ <Camera make="Canon" model="Canon EOS 5D Mark IV" mode="sRaw2">
+ <ID make="Canon" model="EOS 5D Mark IV">Canon EOS 5D Mark IV</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="56032"/>
+ <!-- FIXME: iso50? -->
+ <Hints>
+ <Hint name="sraw_new" value=""/>
+ <Hint name="invert_sraw_wb" value=""/>
+ </Hints>
+ </Camera>
<Camera make="Canon" model="Canon EOS 5DS" decoder_version="6">
<ID make="Canon" model="EOS 5DS">Canon EOS 5DS</ID>
<CFA width="2" height="2">
@@ -724,14 +744,34 @@
<Color x="0" y="1">GREEN</Color>
<Color x="1" y="1">BLUE</Color>
</CFA>
- <Crop x="160" y="64" width="-2" height="0"/>
+ <Crop x="164" y="72" width="-6" height="-8"/>
<Sensor black="2048" white="15181"/>
<Sensor black="2048" white="14466" iso_list="50 100"/>
<BlackAreas>
<Vertical x="0" width="150"/>
- <Horizontal y="2" height="60"/>
+ <Horizontal y="40" height="60"/>
</BlackAreas>
</Camera>
+ <Camera make="Canon" model="Canon EOS 5DS" mode="sRaw1" decoder_version="6">
+ <ID make="Canon" model="EOS 5DS">Canon EOS 5DS</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="52000"/>
+ <Sensor black="0" white="46000" iso_list="50"/>
+ <Hints>
+ <Hint name="sraw_new" value=""/>
+ <Hint name="invert_sraw_wb" value=""/>
+ </Hints>
+ </Camera>
+ <Camera make="Canon" model="Canon EOS 5DS" mode="sRaw2" decoder_version="6">
+ <ID make="Canon" model="EOS 5DS">Canon EOS 5DS</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="52000"/>
+ <Sensor black="0" white="46000" iso_list="50"/>
+ <Hints>
+ <Hint name="sraw_new" value=""/>
+ <Hint name="invert_sraw_wb" value=""/>
+ </Hints>
+ </Camera>
<Camera make="Canon" model="Canon EOS 5DS R" decoder_version="6">
<ID make="Canon" model="EOS 5DS R">Canon EOS 5DS R</ID>
<CFA width="2" height="2">
@@ -740,14 +780,34 @@
<Color x="0" y="1">GREEN</Color>
<Color x="1" y="1">BLUE</Color>
</CFA>
- <Crop x="160" y="64" width="-2" height="0"/>
+ <Crop x="164" y="72" width="-6" height="-8"/>
<Sensor black="2048" white="15181"/>
<Sensor black="2048" white="14466" iso_list="50 100"/>
<BlackAreas>
<Vertical x="0" width="150"/>
- <Horizontal y="2" height="60"/>
+ <Horizontal y="40" height="60"/>
</BlackAreas>
</Camera>
+ <Camera make="Canon" model="Canon EOS 5DS R" mode="sRaw1" decoder_version="6">
+ <ID make="Canon" model="EOS 5DS R">Canon EOS 5DS R</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="52000"/>
+ <Sensor black="0" white="46000" iso_list="50"/>
+ <Hints>
+ <Hint name="sraw_new" value=""/>
+ <Hint name="invert_sraw_wb" value=""/>
+ </Hints>
+ </Camera>
+ <Camera make="Canon" model="Canon EOS 5DS R" mode="sRaw2" decoder_version="6">
+ <ID make="Canon" model="EOS 5DS R">Canon EOS 5DS R</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="52000"/>
+ <Sensor black="0" white="46000" iso_list="50"/>
+ <Hints>
+ <Hint name="sraw_new" value=""/>
+ <Hint name="invert_sraw_wb" value=""/>
+ </Hints>
+ </Camera>
<Camera make="Canon" model="Canon EOS 6D" decoder_version="2">
<ID make="Canon" model="EOS 6D">Canon EOS 6D</ID>
<CFA width="2" height="2">
@@ -966,6 +1026,46 @@
<Alias id="EOS Kiss X80">Canon EOS Kiss X80</Alias>
</Aliases>
</Camera>
+ <Camera make="Canon" model="Canon EOS 2000D">
+ <ID make="Canon" model="EOS 2000D">Canon EOS 2000D</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">BLUE</Color>
+ <Color x="0" y="1">RED</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="78" y="42" width="-4" height="-6"/>
+ <Sensor black="2048" white="15092"/>
+ <Sensor black="2048" white="12277" iso_list="100"/>
+ <BlackAreas>
+ <Vertical x="0" width="70"/>
+ <Horizontal y="4" height="30"/>
+ </BlackAreas>
+ <Aliases>
+ <Alias id="EOS Rebel T7">Canon EOS Rebel T7</Alias>
+ <Alias id="EOS 1500D">Canon EOS 1500D</Alias>
+ </Aliases>
+ </Camera>
+ <Camera make="Canon" model="Canon EOS 4000D">
+ <ID make="Canon" model="EOS 4000D">Canon EOS 4000D</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">BLUE</Color>
+ <Color x="0" y="1">RED</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="146" y="56" width="0" height="0"/>
+ <Sensor black="2051" white="15000"/>
+ <Sensor black="2046" white="12279" iso_list="100"/>
+ <BlackAreas>
+ <Vertical x="0" width="130"/>
+ <Horizontal y="4" height="40"/>
+ </BlackAreas>
+ <Aliases>
+ <Alias id="EOS Rebel T100">Canon EOS Rebel T100</Alias>
+ <Alias id="EOS 3000D">Canon EOS 3000D</Alias>
+ </Aliases>
+ </Camera>
<Camera make="Canon" model="Canon EOS 400D DIGITAL">
<ID make="Canon" model="EOS 400D">Canon EOS 400D</ID>
<CFA width="2" height="2">
@@ -1966,6 +2066,18 @@
<Hint name="wb_offset" value="142"/>
</Hints>
</Camera>
+ <Camera make="GoPro" model="FUSION" mode="dng">
+ <ID make="GoPro" model="FUSION">GoPro FUSION</ID>
+ </Camera>
+ <Camera make="GoPro" model="HERO5 Black" mode="dng">
+ <ID make="GoPro" model="HERO5 Black">GoPro HERO5 Black</ID>
+ </Camera>
+ <Camera make="GoPro" model="HERO6 Black" mode="dng">
+ <ID make="GoPro" model="HERO6 Black">GoPro HERO6 Black</ID>
+ </Camera>
+ <Camera make="GoPro" model="HERO7 Black" mode="dng">
+ <ID make="GoPro" model="HERO7 Black">GoPro HERO7 Black</ID>
+ </Camera>
<Camera make="NIKON CORPORATION" model="NIKON D100" mode="12bit-compressed">
<ID make="Nikon" model="D100">Nikon D100</ID>
<CFA width="2" height="2">
@@ -2140,6 +2252,28 @@
<Crop x="0" y="0" width="-32" height="-8"/>
<Sensor black="0" white="3880"/>
</Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON D2Xs" mode="12bit-compressed">
+ <ID make="Nikon" model="D2Xs">Nikon D2Xs</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-8" height="0"/>
+ <Sensor black="0" white="3880"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON D2Xs" mode="12bit-uncompressed">
+ <ID make="Nikon" model="D2Xs">Nikon D2Xs</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-8" height="0"/>
+ <Sensor black="0" white="3880"/>
+ </Camera>
<Camera make="NIKON CORPORATION" model="NIKON D3" mode="14bit-compressed">
<ID make="Nikon" model="D3">Nikon D3</ID>
<CFA width="2" height="2">
@@ -2415,6 +2549,17 @@
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="150" white="3880"/>
</Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON D3500" mode="12bit-compressed">
+ <ID make="Nikon" model="D3500">Nikon D3500</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="150" white="3972"/>
+ </Camera>
<Camera make="NIKON CORPORATION" model="NIKON D4" mode="14bit-compressed">
<ID make="Nikon" model="D4">Nikon D4</ID>
<CFA width="2" height="2">
@@ -2509,6 +2654,98 @@
<Hint name="msb_override" value=""/>
</Hints>
</Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 6" mode="14bit-compressed">
+ <ID make="Nikon" model="Z 6">Nikon Z 6</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="1008" white="15520"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 6" mode="14bit-uncompressed" supported="no">
+ <ID make="Nikon" model="Z 6">Nikon Z 6</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="1008" white="15520"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 6" mode="12bit-compressed">
+ <ID make="Nikon" model="Z 6">Nikon Z 6</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="251" white="3880"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 6" mode="12bit-uncompressed" supported="no">
+ <ID make="Nikon" model="Z 6">Nikon Z 6</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="251" white="3880"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 7" mode="14bit-compressed">
+ <ID make="Nikon" model="Z 7">Nikon Z 7</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="1008" white="15520"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 7" mode="14bit-uncompressed" supported="no">
+ <!-- something is wrong here with the width/input pitch -->
+ <ID make="Nikon" model="Z 7">Nikon Z 7</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="1008" white="15520"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 7" mode="12bit-compressed">
+ <ID make="Nikon" model="Z 7">Nikon Z 7</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="252" white="3880"/>
+ </Camera>
+ <Camera make="NIKON CORPORATION" model="NIKON Z 7" mode="12bit-uncompressed">
+ <ID make="Nikon" model="Z 7">Nikon Z 7</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="252" white="3880"/>
+ <Hints>
+ <Hint name="msb_override" value=""/>
+ </Hints>
+ </Camera>
<Camera make="NIKON CORPORATION" model="NIKON Df" mode="14bit-compressed">
<ID make="Nikon" model="Df">Nikon Df</ID>
<CFA width="2" height="2">
@@ -3803,6 +4040,20 @@
<Hint name="real_bpp" value="16"/>
</Hints>
</Camera>
+ <Camera make="NIKON CORPORATION" model="COOLPIX P1000" mode="12bit-uncompressed">
+ <ID make="Nikon" model="COOLPIX P1000">Nikon Coolpix P1000</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="200" white="4095"/>
+ <Hints>
+ <Hint name="coolpixmangled" value=""/>
+ </Hints>
+ </Camera>
<Camera make="NIKON" model="E8800" mode="12bit-compressed" decoder_version="3" supported="no"> <!-- need raw sample for whitelevel -->
<ID make="Nikon" model="Coolpix E8800">Nikon Coolpix E8800</ID>
<CFA width="2" height="2">
@@ -3833,376 +4084,171 @@
</Camera>
<Camera make="OLYMPUS OPTICAL CO.,LTD" model="C5050Z">
<ID make="Olympus" model="C5050Z">Olympus C5050Z</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="C5060WZ">
<ID make="Olympus" model="C5060WZ">Olympus C5060WZ</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="C8080WZ">
<ID make="Olympus" model="C8080WZ">Olympus C8080WZ</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="3280" height="2453"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="E-1">
<ID make="Olympus" model="E-1">Olympus E-1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">GREEN</Color>
- <Color x="1" y="0">RED</Color>
- <Color x="0" y="1">BLUE</Color>
- <Color x="1" y="1">GREEN</Color>
- </CFA>
<Crop x="0" y="0" width="2624" height="1966"/>
<Sensor black="65" white="4095"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="TG-4">
<ID make="Olympus" model="TG-4">Olympus TG-4</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">GREEN</Color>
- <Color x="1" y="0">RED</Color>
- <Color x="0" y="1">BLUE</Color>
- <Color x="1" y="1">GREEN</Color>
- </CFA>
<Crop x="16" y="8" width="-16" height="-8"/>
<Sensor black="0" white="4000"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="TG-5">
<ID make="Olympus" model="TG-5">Olympus TG-5</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">GREEN</Color>
- <Color x="1" y="0">RED</Color>
- <Color x="0" y="1">BLUE</Color>
- <Color x="1" y="1">GREEN</Color>
- </CFA>
<Crop x="0" y="0" width="-24" height="0"/>
<Sensor black="256" white="4000"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="C7070WZ">
<ID make="Olympus" model="C7070WZ">Olympus C7070WZ</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3088" height="2309"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-3">
<ID make="Olympus" model="E-3">Olympus E-3</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3720" height="2800"/>
<Sensor black="65" white="4015"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-30">
<ID make="Olympus" model="E-30">Olympus E-30</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="-6" height="-2"/>
<Sensor black="65" white="4015"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-300" decoder_version="3">
<ID make="Olympus" model="E-300">Olympus E-300</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3340" height="2504"/>
<Sensor black="63" white="4095"/>
- <Hints>
- <Hint name="force_uncompressed" value=""/>
- <Hint name="packed_with_control" value=""/>
- </Hints>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-330" decoder_version="3">
<ID make="Olympus" model="E-330">Olympus E-330</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3250" height="2450"/>
<Sensor black="77" white="4095"/>
- <Hints>
- <Hint name="force_uncompressed" value=""/>
- <Hint name="packed_with_control" value=""/>
- </Hints>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-400">
<ID make="Olympus" model="E-400">Olympus E-400</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">GREEN</Color>
- <Color x="1" y="0">RED</Color>
- <Color x="0" y="1">BLUE</Color>
- <Color x="1" y="1">GREEN</Color>
- </CFA>
<Crop x="0" y="0" width="3768" height="2840"/>
<Sensor black="96" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-410">
<ID make="Olympus" model="E-410">Olympus E-410</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3720" height="2800"/>
<Sensor black="72" white="3500"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-420">
<ID make="Olympus" model="E-420">Olympus E-420</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3720" height="2800"/>
<Sensor black="68" white="4015"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-450">
<ID make="Olympus" model="E-450">Olympus E-450</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="69" white="4015"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-500" decoder_version="3">
<ID make="Olympus" model="E-500">Olympus E-500</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3340" height="2504"/>
<Sensor black="63" white="3967"/>
- <Hints>
- <Hint name="force_uncompressed" value=""/>
- <Hint name="packed_with_control" value=""/>
- </Hints>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-510">
<ID make="Olympus" model="E-510">Olympus E-510</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3720" height="2800"/>
<Sensor black="72" white="3500"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-520">
<ID make="Olympus" model="E-520">Olympus E-520</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3720" height="2800"/>
<Sensor black="69" white="4015"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-600">
<ID make="Olympus" model="E-600">Olympus E-600</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="4096" height="3072"/>
<Sensor black="64" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-620">
<ID make="Olympus" model="E-620">Olympus E-620</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="4096" height="3072"/>
<Sensor black="64" white="4095"/>
</Camera>
+ <Camera make="OLYMPUS IMAGING CORP." model="SH-2">
+ <ID make="Olympus" model="SH-2">Olympus SH-2</ID>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="200" white="4000"/>
+ </Camera>
<Camera make="OLYMPUS IMAGING CORP." model="SP320">
<ID make="Olympus" model="SP320">Olympus SP320</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="SP350">
<ID make="Olympus" model="SP350">Olympus SP350</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="3280" height="2453"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="SP500UZ">
<ID make="Olympus" model="SP500UZ">Olympus SP500UZ</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">GREEN</Color>
- <Color x="1" y="0">BLUE</Color>
- <Color x="0" y="1">RED</Color>
- <Color x="1" y="1">GREEN</Color>
- </CFA>
<Crop x="0" y="0" width="2832" height="2117"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-5">
<ID make="Olympus" model="E-5">Olympus E-5</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="-4" height="0"/>
<Sensor black="80" white="4095"/>
</Camera>
<Camera make="OLYMPUS OPTICAL CO.,LTD" model="E-10">
<ID make="Olympus" model="E-10">Olympus E-10</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="2256" height="1684"/>
<Sensor black="32" white="1023"/>
</Camera>
<Camera make="OLYMPUS OPTICAL CO.,LTD" model="E-20,E-20N,E-20P">
<ID make="Olympus" model="E-20">Olympus E-20</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="2576" height="1924"/>
<Sensor black="0" white="4092"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-M1">
<ID make="Olympus" model="E-M1">Olympus E-M1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="255" white="4095"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="E-M1MarkII">
<ID make="Olympus" model="E-M1MarkII">Olympus E-M1 Mark II</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="254" white="4000"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-M10">
<ID make="Olympus" model="E-M10">Olympus E-M10</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="254" white="4000"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="E-M10MarkII">
<ID make="Olympus" model="E-M10 Mark II">Olympus E-M10 Mark II</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="254" white="4000"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="E-M10 Mark III">
<ID make="Olympus" model="E-M10 Mark III">Olympus E-M10 Mark III</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="254" white="4000"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-M5">
<ID make="Olympus" model="E-M5">Olympus E-M5</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="255" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-M5MarkII">
<ID make="Olympus" model="E-M5 Mark II">Olympus E-M5 Mark II</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="254" white="4000"/>
<Sensor black="249" white="4000" iso_min="800" iso_max="3199"/>
@@ -4213,34 +4259,16 @@
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-P1">
<ID make="Olympus" model="E-P1">Olympus E-P1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="4094" height="3082"/>
<Sensor black="55" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PL1">
<ID make="Olympus" model="E-PL1">Olympus E-PL1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="4094" height="3082"/>
<Sensor black="55" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PL2">
<ID make="Olympus" model="E-PL2">Olympus E-PL2</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="-4" height="0"/>
<Sensor black="45" white="4095"/>
<BlackAreas>
@@ -4249,12 +4277,6 @@
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PL3">
<ID make="Olympus" model="E-PL3">Olympus E-PL3</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="-30" height="0"/>
<Sensor black="45" white="4095"/>
<BlackAreas>
@@ -4263,67 +4285,36 @@
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PL5">
<ID make="Olympus" model="E-PL5">Olympus E-PL5</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PL6">
<ID make="Olympus" model="E-PL6">Olympus E-PL6</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PL7">
<ID make="Olympus" model="E-PL7">Olympus E-PL7</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="0" white="4095"/>
</Camera>
+ <Camera make="OLYMPUS CORPORATION" model="E-PL8">
+ <ID make="Olympus" model="E-PL8">Olympus E-PL8</ID>
+ <Crop x="8" y="8" width="-24" height="-8"/>
+ <Sensor black="254" white="4095"/>
+ </Camera>
<Camera make="OLYMPUS CORPORATION" model="E-PL9">
<ID make="Olympus" model="E-PL9">Olympus E-PL9</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="248" white="4000"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-P5">
<ID make="Olympus" model="E-P5">Olympus E-P5</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="250" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PM1">
<ID make="Olympus" model="E-PM1">Olympus E-PM1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="-24" height="0"/>
<Sensor black="45" white="4095"/>
<BlackAreas>
@@ -4332,108 +4323,46 @@
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-PM2">
<ID make="Olympus" model="E-PM2">Olympus E-PM2</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="8" y="8" width="-24" height="-8"/>
<Sensor black="250" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-P2">
<ID make="Olympus" model="E-P2">Olympus E-P2</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="55" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="E-P3">
<ID make="Olympus" model="E-P3">Olympus E-P3</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="-26" height="0"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS CORPORATION" model="PEN-F">
<ID make="Olympus" model="PEN-F">Olympus PEN-F</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="254" white="4000"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="XZ-1">
<ID make="Olympus" model="XZ-1">Olympus XZ-1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="-2"/>
<Sensor black="55" white="3972"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="XZ-2" decoder_version="3">
<ID make="Olympus" model="XZ-2">Olympus XZ-2</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="-2"/>
<Sensor black="200" white="4092"/>
- <Hints>
- <Hint name="force_uncompressed" value=""/>
- <Hint name="jpeg32_bitorder" value=""/>
- </Hints>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="XZ-10" decoder_version="3">
<ID make="Olympus" model="XZ-10">Olympus XZ-10</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="200" white="3900"/>
- <Hints>
- <Hint name="force_uncompressed" value=""/>
- <Hint name="jpeg32_bitorder" value=""/>
- </Hints>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="SP570UZ">
<ID make="Olympus" model="SP570UZ">Olympus SP570UZ</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">BLUE</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">RED</Color>
- </CFA>
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="OLYMPUS IMAGING CORP." model="STYLUS1">
<ID make="Olympus" model="Stylus1">Olympus Stylus1</ID>
- <CFA width="2" height="2">
- <Color x="0" y="0">RED</Color>
- <Color x="1" y="0">GREEN</Color>
- <Color x="0" y="1">GREEN</Color>
- <Color x="1" y="1">BLUE</Color>
- </CFA>
<Crop x="0" y="0" width="-14" height="0"/>
<Sensor black="200" white="3900"/>
<Aliases>
@@ -5759,6 +5688,34 @@
<Alias>DMC-FZ38</Alias>
</Aliases>
</Camera>
+ <Camera make="Panasonic" model="DMC-FZ35" mode="3:2">
+ <ID make="Panasonic" model="DMC-FZ35">Panasonic DMC-FZ35</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-42" height="-4"/>
+ <Sensor black="143" white="3986"/>
+ <Aliases>
+ <Alias>DMC-FZ38</Alias>
+ </Aliases>
+ </Camera>
+ <Camera make="Panasonic" model="DMC-FZ35" mode="16:9">
+ <ID make="Panasonic" model="DMC-FZ35">Panasonic DMC-FZ35</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-42" height="-4"/>
+ <Sensor black="143" white="3986"/>
+ <Aliases>
+ <Alias>DMC-FZ38</Alias>
+ </Aliases>
+ </Camera>
<Camera make="Panasonic" model = "DMC-FZ35">
<ID make="Panasonic" model="DMC-FZ35">Panasonic DMC-FZ35</ID>
<!-- Default Guess -->
@@ -6091,6 +6048,7 @@
<Sensor black="143" white="4095"/>
<Aliases>
<Alias>DMC-GX80</Alias>
+ <Alias>DMC-GX7MK2</Alias>
</Aliases>
</Camera>
<Camera make="Panasonic" model="DMC-GX85" mode="4:3">
@@ -6105,6 +6063,7 @@
<Sensor black="143" white="4095"/>
<Aliases>
<Alias>DMC-GX80</Alias>
+ <Alias>DMC-GX7MK2</Alias>
</Aliases>
</Camera>
<!-- Default guess -->
@@ -6941,6 +6900,61 @@
<Crop x="0" y="0" width="-144" height="0"/>
<Sensor black="143" white="4095"/>
</Camera>
+ <Camera make="Panasonic" model="DC-LX100M2">
+ <ID make="Panasonic" model="DC-LX100M2">Panasonic DC-LX100M2</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="143" white="4095"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-LX100M2" mode="4:3">
+ <ID make="Panasonic" model="DC-LX100M2">Panasonic DC-LX100M2</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="10" y="6" width="-60" height="-4"/>
+ <Sensor black="143" white="4095"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-LX100M2" mode="1:1">
+ <ID make="Panasonic" model="DC-LX100M2">Panasonic DC-LX100M2</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="0" y="6" width="-130" height="-4"/>
+ <Sensor black="144" white="4095"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-LX100M2" mode="16:9">
+ <ID make="Panasonic" model="DC-LX100M2">Panasonic DC-LX100M2</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="10" y="0" width="-90" height="0"/>
+ <Sensor black="144" white="4095"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-LX100M2" mode="3:2">
+ <ID make="Panasonic" model="DC-LX100M2">Panasonic DC-LX100M2</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="4" y="0" width="-90" height="0"/>
+ <Sensor black="144" white="4095"/>
+ </Camera>
<Camera make="Panasonic" model="DMC-TZ60">
<CFA width="2" height="2">
<Color x="0" y="0">RED</Color>
@@ -7213,6 +7227,7 @@
<Crop x="0" y="0" width="-128" height="0"/>
<Sensor black="143" white="4095"/>
<Aliases>
+ <Alias>DC-FZ80</Alias>
<Alias>DMC-FZ80</Alias>
<Alias>DMC-FZ85</Alias>
</Aliases>
@@ -7228,6 +7243,7 @@
<Crop x="0" y="0" width="-128" height="0"/>
<Sensor black="143" white="4095"/>
<Aliases>
+ <Alias>DC-FZ80</Alias>
<Alias>DMC-FZ80</Alias>
<Alias>DMC-FZ85</Alias>
</Aliases>
@@ -7254,6 +7270,61 @@
<Crop x="0" y="0" width="-56" height="0"/>
<Sensor black="143" white="4095"/>
</Camera>
+ <Camera make="Panasonic" model="DC-GH5S" decoder_version="3">
+ <ID make="Panasonic" model="DC-GH5S">Panasonic DC-GH5S</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="510" white="8000"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-GH5S" decoder_version="3" mode="4:3">
+ <ID make="Panasonic" model="DC-GH5S">Panasonic DC-GH5S</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-40" height="0"/>
+ <Sensor black="510" white="8000"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-GH5S" decoder_version="3" mode="3:2">
+ <ID make="Panasonic" model="DC-GH5S">Panasonic DC-GH5S</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-24" height="0"/>
+ <Sensor black="510" white="8000"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-GH5S" decoder_version="3" mode="16:9">
+ <ID make="Panasonic" model="DC-GH5S">Panasonic DC-GH5S</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-68" height="0"/>
+ <Sensor black="510" white="8000"/>
+ </Camera>
+ <Camera make="Panasonic" model="DC-GH5S" decoder_version="3" mode="1:1">
+ <ID make="Panasonic" model="DC-GH5S">Panasonic DC-GH5S</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-32" height="0"/>
+ <Sensor black="510" white="8000"/>
+ </Camera>
<Camera make="Panasonic" model="DC-G9">
<ID make="Panasonic" model="DC-G9">Panasonic DC-G9</ID>
<CFA width="2" height="2">
@@ -7276,6 +7347,36 @@
<Crop x="0" y="0" width="-58" height="0"/>
<Sensor black="148" white="4095"/>
</Camera>
+ <Camera make="Panasonic" model="DC-GF9">
+ <ID make="Panasonic" model="DC-GF9">Panasonic DC-GF9</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-208" height="0"/>
+ <Sensor black="143" white="4095"/>
+ <Aliases>
+ <Alias>DC-GX800</Alias>
+ <Alias>DC-GX850</Alias>
+ </Aliases>
+ </Camera>
+ <Camera make="Panasonic" model="DC-GF9" mode="4:3">
+ <ID make="Panasonic" model="DC-GF9">Panasonic DC-GF9</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-208" height="0"/>
+ <Sensor black="143" white="4095"/>
+ <Aliases>
+ <Alias>DC-GX800</Alias>
+ <Alias>DC-GX850</Alias>
+ </Aliases>
+ </Camera>
<Camera make="Panasonic" model="DC-GX9">
<ID make="Panasonic" model="DC-GX9">Panasonic DC-GX9</ID>
<CFA width="2" height="2">
@@ -7332,6 +7433,34 @@
<Alias>DC-FZ93</Alias>
</Aliases>
</Camera>
+ <Camera make="Panasonic" model="DC-TZ202">
+ <ID make="Panasonic" model="DC-TZ202">Panasonic DC-ZS200</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">BLUE</Color>
+ <Color x="0" y="1">RED</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="142" white="4095"/>
+ <Aliases>
+ <Alias>DC-TZ200</Alias>
+ </Aliases>
+ </Camera>
+ <Camera make="Panasonic" model="DC-TZ202" mode="3:2">
+ <ID make="Panasonic" model="DC-TZ202">Panasonic DC-ZS200</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">BLUE</Color>
+ <Color x="0" y="1">RED</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="142" white="4095"/>
+ <Aliases>
+ <Alias>DC-TZ200</Alias>
+ </Aliases>
+ </Camera>
<Camera make="PENTAX Corporation" model="PENTAX K100D">
<ID make="Pentax" model="K100D">Pentax K100D</ID>
<CFA width="2" height="2">
@@ -7519,6 +7648,17 @@
<Crop x="4" y="18" width="-10" height="-2"/>
<Sensor black="64" white="16316"/>
</Camera>
+ <Camera make="RICOH IMAGING COMPANY, LTD." model="PENTAX K-1 Mark II">
+ <ID make="Pentax" model="K-1 Mark II">Pentax K-1 Mark II</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="6" y="28" width="-8" height="0"/>
+ <Sensor black="64" white="16316"/>
+ </Camera>
<Camera make="RICOH IMAGING COMPANY, LTD." model="PENTAX K-3">
<ID make="Pentax" model="K-3">Pentax K-3</ID>
<CFA width="2" height="2">
@@ -7549,7 +7689,7 @@
<Color x="0" y="1">GREEN</Color>
<Color x="1" y="1">RED</Color>
</CFA>
- <Crop x="12" y="0" width="-34" height="0"/>
+ <Crop x="12" y="0" width="-38" height="-60"/>
<Sensor black="512" white="16383"/>
<BlackAreas>
<Vertical x="0" width="8"/>
@@ -7666,6 +7806,28 @@
<Crop x="0" y="0" width="3900" height="2616"/>
<Sensor black="0" white="4095"/>
</Camera>
+ <Camera make="PENTAX" model="PENTAX 645D">
+ <ID make="Pentax" model="645D">Pentax 645D</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">BLUE</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">RED</Color>
+ </CFA>
+ <Crop x="54" y="32" width="-50" height="-22"/>
+ <Sensor black="0" white="15767"/>
+ </Camera>
+ <Camera make="RICOH IMAGING COMPANY, LTD." model="PENTAX 645Z">
+ <ID make="Pentax" model="645Z">Pentax 645Z</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="48" y="0" width="-60" height="0"/>
+ <Sensor black="1" white="16316"/>
+ </Camera>
<Camera make="SAMSUNG" model="EX2F">
<ID make="Samsung" model="EX2F">Samsung EX2F</ID>
<CFA width="2" height="2">
@@ -8045,6 +8207,17 @@
<Crop x="0" y="0" width="-8" height="0"/>
<Sensor black="800" white="16300"/>
</Camera>
+ <Camera make="SONY" model="DSC-RX100M5A">
+ <ID make="Sony" model="DSC-RX100M5A">Sony DSC-RX100M5A</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="-8" height="0"/>
+ <Sensor black="800" white="16300"/>
+ </Camera>
<Camera make="SONY" model="DSC-RX1R">
<ID make="Sony" model="DSC-RX1R">Sony DSC-RX1R</ID>
<CFA width="2" height="2">
@@ -8509,7 +8682,7 @@
<Color x="0" y="1">GREEN</Color>
<Color x="1" y="1">BLUE</Color>
</CFA>
- <Crop x="0" y="0" width="0" height="0"/>
+ <Crop x="0" y="0" width="-20" height="0"/>
<Sensor black="512" white="16383"/>
</Camera>
<Camera make="SONY" model="ILCE-7S">
@@ -9280,6 +9453,20 @@
<Hint name="jpeg32_bitorder" value=""/>
</Hints>
</Camera>
+ <Camera make="FUJIFILM" model="X-A5">
+ <ID make="Fujifilm" model="X-A5">Fujifilm X-A5</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="1024" white="16383"/>
+ <Hints>
+ <Hint name="jpeg32_bitorder" value=""/>
+ </Hints>
+ </Camera>
<Camera make="FUJIFILM" model="XQ1">
<ID make="Fujifilm" model="XQ1">Fujifilm XQ1</ID>
<CFA2 width="6" height="6">
@@ -9397,6 +9584,32 @@
<Crop x="0" y="12" width="-16" height="-12"/>
<Sensor black="1024" white="16383"/>
</Camera>
+ <Camera make="FUJIFILM" model="X-T3">
+ <ID make="Fujifilm" model="X-T3">Fujifilm X-T3</ID>
+ <CFA2 width="6" height="6">
+ <ColorRow y="0">GGRGGB</ColorRow>
+ <ColorRow y="1">GGBGGR</ColorRow>
+ <ColorRow y="2">BRGRBG</ColorRow>
+ <ColorRow y="3">GGBGGR</ColorRow>
+ <ColorRow y="4">GGRGGB</ColorRow>
+ <ColorRow y="5">RBGBRG</ColorRow>
+ </CFA2>
+ <Crop x="0" y="8" width="-134" height="-6"/>
+ <Sensor black="1022" white="16383"/>
+ </Camera>
+ <Camera make="FUJIFILM" model="X-T3" mode="compressed">
+ <ID make="Fujifilm" model="X-T3">Fujifilm X-T3</ID>
+ <CFA2 width="6" height="6">
+ <ColorRow y="0">GGRGGB</ColorRow>
+ <ColorRow y="1">GGBGGR</ColorRow>
+ <ColorRow y="2">BRGRBG</ColorRow>
+ <ColorRow y="3">GGBGGR</ColorRow>
+ <ColorRow y="4">GGRGGB</ColorRow>
+ <ColorRow y="5">RBGBRG</ColorRow>
+ </CFA2>
+ <Crop x="0" y="8" width="-134" height="-6"/>
+ <Sensor black="1022" white="16383"/>
+ </Camera>
<Camera make="FUJIFILM" model="X-T10">
<ID make="Fujifilm" model="X-T10">Fujifilm X-T10</ID>
<CFA2 width="6" height="6">
@@ -9436,6 +9649,20 @@
<Crop x="0" y="12" width="-16" height="-12"/>
<Sensor black="1024" white="16383"/>
</Camera>
+ <Camera make="FUJIFILM" model="X-T100">
+ <ID make="Fujifilm" model="X-T100">Fujifilm X-T100</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="1024" white="16383"/>
+ <Hints>
+ <Hint name="jpeg32_bitorder" value=""/>
+ </Hints>
+ </Camera>
<Camera make="KONICA MINOLTA" model="DYNAX 5D">
<ID make="Minolta" model="Dynax 5D">Konica Minolta Maxxum 5D</ID>
<CFA width="2" height="2">
@@ -9560,6 +9787,17 @@
<Hint name="srf_format" value=""/>
</Hints>
</Camera>
+ <Camera make="SONY" model="DSC-HX99">
+ <ID make="Sony" model="DSC-HX99">Sony DSC-HX99</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="10" y="0" width="-20" height="-10"/>
+ <Sensor black="800" white="16300"/>
+ </Camera>
<Camera make="SONY" model="DSC-R1">
<ID make="Sony" model="DSC-R1">Sony DSC-R1</ID>
<CFA width="2" height="2">
@@ -9701,6 +9939,17 @@
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="0" white="15000"/>
</Camera>
+ <Camera make="Phase One A/S" model="P65+">
+ <ID make="Phase One" model="P65+">Phase One P65+</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="42" y="12" width="-18" height="-48"/>
+ <Sensor black="0" white="16383"/>
+ </Camera>
<Camera make="Phase One A/S" model="IQ140">
<ID make="Phase One" model="IQ140">Phase One IQ140</ID>
<CFA width="2" height="2">
@@ -9724,6 +9973,18 @@
<Sensor black="1024" white="65535"/>
</Camera>
<Camera make="Kodak" model="DCS Pro SLR/n">
+ <ID make="Kodak" model="DCS Pro SLR/n">Kodak DCS Pro SLR/n</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">RED</Color>
+ <Color x="0" y="1">BLUE</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="4095"/>
+ </Camera>
+ <Camera make="Kodak" model="DCS Pro 14nx">
+ <ID make="Kodak" model="DCS Pro 14nx">Kodak DCS Pro 14nx</ID>
<CFA width="2" height="2">
<Color x="0" y="0">GREEN</Color>
<Color x="1" y="0">RED</Color>
@@ -9744,6 +10005,17 @@
<Crop x="3" y="0" width="-3" height="0"/>
<Sensor black="7" white="6664"/>
</Camera>
+ <Camera make="Kodak" model="DCS520C">
+ <ID make="Kodak" model="DCS520C">Kodak DCS520C</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">RED</Color>
+ <Color x="0" y="1">BLUE</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="176" white="4095"/>
+ </Camera>
<Camera make="Kodak" model="DCS560C">
<ID make="Kodak" model="DCS560C">Kodak DCS560C</ID>
<CFA width="2" height="2">
@@ -9753,7 +10025,7 @@
<Color x="1" y="1">GREEN</Color>
</CFA>
<Crop x="0" y="0" width="0" height="0"/>
- <Sensor black="0" white="4095"/>
+ <Sensor black="208" white="4095"/>
</Camera>
<Camera make="KODAK" model="EOSDCS1B FILE VERSION 3">
<ID make="Kodak" model="EOS DCS 1">Kodak EOSDCS1</ID>
@@ -9777,6 +10049,17 @@
<Crop x="6" y="0" width="-6" height="0"/>
<Sensor black="0" white="7855"/>
</Camera>
+ <Camera make="Kodak" model="DCS760C">
+ <ID make="Kodak" model="DCS760C">Kodak DCS760C</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">GREEN</Color>
+ <Color x="1" y="0">RED</Color>
+ <Color x="0" y="1">BLUE</Color>
+ <Color x="1" y="1">GREEN</Color>
+ </CFA>
+ <Crop x="0" y="0" width="0" height="0"/>
+ <Sensor black="0" white="3500"/>
+ </Camera>
<Camera make="EASTMAN KODAK COMPANY" model="KODAK P880 ZOOM DIGITAL CAMERA">
<ID make="Kodak" model="P880">Kodak P880</ID>
<CFA width="2" height="2">
@@ -9844,6 +10127,17 @@
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="0" white="32767"/>
</Camera>
+ <Camera make="Hasselblad" model="Hasselblad CFV-50">
+ <ID make="Hasselblad" model="CFV-50">Hasselblad 50-Coated</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="48" y="6" width="-42" height="-82"/>
+ <Sensor black="256" white="65535"/>
+ </Camera>
<Camera make="Hasselblad" model="Hasselblad H3D">
<ID make="Hasselblad" model="H3D">Hasselblad 39-Coated</ID>
<CFA width="2" height="2">
@@ -9852,9 +10146,31 @@
<Color x="0" y="1">GREEN</Color>
<Color x="1" y="1">BLUE</Color>
</CFA>
- <Crop x="0" y="0" width="0" height="0"/>
+ <Crop x="10" y="6" width="-8" height="-10"/>
<Sensor black="0" white="31456"/>
</Camera>
+ <Camera make="Hasselblad" model="Hasselblad H5D-40">
+ <ID make="Hasselblad" model="H5D-40">Hasselblad 40-Coated5</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="44" y="6" width="-42" height="-82"/>
+ <Sensor black="256" white="62914"/>
+ </Camera>
+ <Camera make="Hasselblad" model="Hasselblad H5D-50c">
+ <ID make="Hasselblad" model="H5D-50c">Hasselblad 50-15-Coated5</ID>
+ <CFA width="2" height="2">
+ <Color x="0" y="0">RED</Color>
+ <Color x="1" y="0">GREEN</Color>
+ <Color x="0" y="1">GREEN</Color>
+ <Color x="1" y="1">BLUE</Color>
+ </CFA>
+ <Crop x="50" y="104" width="-48" height="0"/>
+ <Sensor black="256" white="62914"/>
+ </Camera>
<Camera make="Hasselblad" model="Flash Sync">
<ID make="Hasselblad" model="CF132">Hasselblad 22-Uncoated</ID>
<CFA width="2" height="2">
@@ -9872,6 +10188,9 @@
<Camera make="PENTAX" model="PENTAX 645D" mode="dng">
<ID make="Pentax" model="645D">PENTAX 645D</ID>
</Camera>
+ <Camera make="PENTAX" model="PENTAX 645Z" mode="dng">
+ <ID make="Pentax" model="645Z">PENTAX 645Z</ID>
+ </Camera>
<Camera make="PENTAX" model="PENTAX K-01" mode="dng">
<ID make="Pentax" model="K-01">PENTAX K-01</ID>
</Camera>
diff --git a/src/external/rawspeed/data/cameras.xsd b/src/external/rawspeed/data/cameras.xsd
index 04b2e943f..0580d1398 100644
--- a/src/external/rawspeed/data/cameras.xsd
+++ b/src/external/rawspeed/data/cameras.xsd
@@ -11,7 +11,7 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:simpleType name="IDTypeType">
<xs:restriction base="xs:string">
- <xs:pattern value="[a-zA-Z0-9 \-*()]{2,38}"/>
+ <xs:pattern value="[a-zA-Z0-9 \-*()/+]{2,38}"/>
<xs:minLength value="2"/>
<xs:maxLength value="38"/>
</xs:restriction>
@@ -25,6 +25,7 @@
<xs:enumeration value="Epson"/>
<xs:enumeration value="Fujifilm"/>
<xs:enumeration value="GITUP"/>
+ <xs:enumeration value="GoPro"/>
<xs:enumeration value="Hasselblad"/>
<xs:enumeration value="Kodak"/>
<xs:enumeration value="LG"/>
@@ -50,7 +51,7 @@
</xs:simpleType>
<xs:simpleType name="IDTypeModelType">
<xs:restriction base="xs:string">
- <xs:pattern value="[a-zA-Z0-9 \-*()]{1,23}"/>
+ <xs:pattern value="[a-zA-Z0-9 \-*()/+]{1,23}"/>
<xs:minLength value="1"/>
<xs:maxLength value="23"/>
</xs:restriction>
@@ -375,6 +376,7 @@
<xs:enumeration value="Foculus"/>
<xs:enumeration value="GITUP"/>
<xs:enumeration value="Generic"/>
+ <xs:enumeration value="GoPro"/>
<xs:enumeration value="Hasselblad"/>
<xs:enumeration value="KODAK"/>
<xs:enumeration value="KONICA MINOLTA"/>
@@ -428,7 +430,7 @@
</xs:simpleType>
<xs:simpleType name="CameraModelType">
<xs:restriction base="xs:string">
- <xs:pattern value="[a-zA-Z0-9 \-().,/*]{0,51}"/>
+ <xs:pattern value="[a-zA-Z0-9 \-().,/*+]{0,51}"/>
<xs:minLength value="0"/>
<xs:maxLength value="51"/>
</xs:restriction>
diff --git a/src/external/rawspeed/fuzz/CMakeLists.txt b/src/external/rawspeed/fuzz/CMakeLists.txt
index 0f3cac4c7..755b956cc 100644
--- a/src/external/rawspeed/fuzz/CMakeLists.txt
+++ b/src/external/rawspeed/fuzz/CMakeLists.txt
@@ -29,10 +29,6 @@ if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_BUILD_TYPE STREQUAL "FU
"${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer_dummy_main.cpp"
)
- if(WITH_OPENMP AND OPENMP_FOUND AND TARGET OpenMP::OpenMP)
- target_link_libraries(rawspeed_fuzz PUBLIC OpenMP::OpenMP)
- endif()
-
macro(add_fuzz_target fuzzer)
add_fuzz_target__base(${fuzzer})
endmacro()
diff --git a/src/external/rawspeed/fuzz/all-fuzzers.txt b/src/external/rawspeed/fuzz/all-fuzzers.txt
index d8872b1cf..7c2013a94 100644
--- a/src/external/rawspeed/fuzz/all-fuzzers.txt
+++ b/src/external/rawspeed/fuzz/all-fuzzers.txt
@@ -7,22 +7,74 @@ FiffParserFuzzer-GetDecoder
FiffParserFuzzer-GetDecoder-Decode
FujiDecompressorFuzzer
HasselbladDecompressorFuzzer
-HuffmanTableFuzzer-BitPumpJPEG-FullDecode
-HuffmanTableFuzzer-BitPumpJPEG-NoFullDecode
-HuffmanTableFuzzer-BitPumpLSB-FullDecode
-HuffmanTableFuzzer-BitPumpLSB-NoFullDecode
-HuffmanTableFuzzer-BitPumpMSB-FullDecode
-HuffmanTableFuzzer-BitPumpMSB-NoFullDecode
-HuffmanTableFuzzer-BitPumpMSB16-FullDecode
-HuffmanTableFuzzer-BitPumpMSB16-NoFullDecode
-HuffmanTableFuzzer-BitPumpMSB32-FullDecode
-HuffmanTableFuzzer-BitPumpMSB32-NoFullDecode
+HuffmanTableFuzzer-LUTVsLookup-BitPumpJPEG-FullDecode
+HuffmanTableFuzzer-LUTVsLookup-BitPumpJPEG-NoFullDecode
+HuffmanTableFuzzer-LUTVsLookup-BitPumpMSB-FullDecode
+HuffmanTableFuzzer-LUTVsLookup-BitPumpMSB-NoFullDecode
+HuffmanTableFuzzer-LUTVsLookup-BitPumpMSB32-FullDecode
+HuffmanTableFuzzer-LUTVsLookup-BitPumpMSB32-NoFullDecode
+HuffmanTableFuzzer-LUTVsTree-BitPumpJPEG-FullDecode
+HuffmanTableFuzzer-LUTVsTree-BitPumpJPEG-NoFullDecode
+HuffmanTableFuzzer-LUTVsTree-BitPumpMSB-FullDecode
+HuffmanTableFuzzer-LUTVsTree-BitPumpMSB-NoFullDecode
+HuffmanTableFuzzer-LUTVsTree-BitPumpMSB32-FullDecode
+HuffmanTableFuzzer-LUTVsTree-BitPumpMSB32-NoFullDecode
+HuffmanTableFuzzer-LUTVsVector-BitPumpJPEG-FullDecode
+HuffmanTableFuzzer-LUTVsVector-BitPumpJPEG-NoFullDecode
+HuffmanTableFuzzer-LUTVsVector-BitPumpMSB-FullDecode
+HuffmanTableFuzzer-LUTVsVector-BitPumpMSB-NoFullDecode
+HuffmanTableFuzzer-LUTVsVector-BitPumpMSB32-FullDecode
+HuffmanTableFuzzer-LUTVsVector-BitPumpMSB32-NoFullDecode
+HuffmanTableFuzzer-LookupVsTree-BitPumpJPEG-FullDecode
+HuffmanTableFuzzer-LookupVsTree-BitPumpJPEG-NoFullDecode
+HuffmanTableFuzzer-LookupVsTree-BitPumpMSB-FullDecode
+HuffmanTableFuzzer-LookupVsTree-BitPumpMSB-NoFullDecode
+HuffmanTableFuzzer-LookupVsTree-BitPumpMSB32-FullDecode
+HuffmanTableFuzzer-LookupVsTree-BitPumpMSB32-NoFullDecode
+HuffmanTableFuzzer-LookupVsVector-BitPumpJPEG-FullDecode
+HuffmanTableFuzzer-LookupVsVector-BitPumpJPEG-NoFullDecode
+HuffmanTableFuzzer-LookupVsVector-BitPumpMSB-FullDecode
+HuffmanTableFuzzer-LookupVsVector-BitPumpMSB-NoFullDecode
+HuffmanTableFuzzer-LookupVsVector-BitPumpMSB32-FullDecode
+HuffmanTableFuzzer-LookupVsVector-BitPumpMSB32-NoFullDecode
+HuffmanTableFuzzer-TreeVsVector-BitPumpJPEG-FullDecode
+HuffmanTableFuzzer-TreeVsVector-BitPumpJPEG-NoFullDecode
+HuffmanTableFuzzer-TreeVsVector-BitPumpMSB-FullDecode
+HuffmanTableFuzzer-TreeVsVector-BitPumpMSB-NoFullDecode
+HuffmanTableFuzzer-TreeVsVector-BitPumpMSB32-FullDecode
+HuffmanTableFuzzer-TreeVsVector-BitPumpMSB32-NoFullDecode
+HuffmanTableLUTFuzzer-BitPumpJPEG-FullDecode
+HuffmanTableLUTFuzzer-BitPumpJPEG-NoFullDecode
+HuffmanTableLUTFuzzer-BitPumpMSB-FullDecode
+HuffmanTableLUTFuzzer-BitPumpMSB-NoFullDecode
+HuffmanTableLUTFuzzer-BitPumpMSB32-FullDecode
+HuffmanTableLUTFuzzer-BitPumpMSB32-NoFullDecode
+HuffmanTableLookupFuzzer-BitPumpJPEG-FullDecode
+HuffmanTableLookupFuzzer-BitPumpJPEG-NoFullDecode
+HuffmanTableLookupFuzzer-BitPumpMSB-FullDecode
+HuffmanTableLookupFuzzer-BitPumpMSB-NoFullDecode
+HuffmanTableLookupFuzzer-BitPumpMSB32-FullDecode
+HuffmanTableLookupFuzzer-BitPumpMSB32-NoFullDecode
+HuffmanTableTreeFuzzer-BitPumpJPEG-FullDecode
+HuffmanTableTreeFuzzer-BitPumpJPEG-NoFullDecode
+HuffmanTableTreeFuzzer-BitPumpMSB-FullDecode
+HuffmanTableTreeFuzzer-BitPumpMSB-NoFullDecode
+HuffmanTableTreeFuzzer-BitPumpMSB32-FullDecode
+HuffmanTableTreeFuzzer-BitPumpMSB32-NoFullDecode
+HuffmanTableVectorFuzzer-BitPumpJPEG-FullDecode
+HuffmanTableVectorFuzzer-BitPumpJPEG-NoFullDecode
+HuffmanTableVectorFuzzer-BitPumpMSB-FullDecode
+HuffmanTableVectorFuzzer-BitPumpMSB-NoFullDecode
+HuffmanTableVectorFuzzer-BitPumpMSB32-FullDecode
+HuffmanTableVectorFuzzer-BitPumpMSB32-NoFullDecode
KodakDecompressorFuzzer
LJpegDecompressorFuzzer
NikonDecompressorFuzzer
OlympusDecompressorFuzzer
PanasonicDecompressorFuzzer
+PanasonicDecompressorV5Fuzzer
PentaxDecompressorFuzzer
+PhaseOneDecompressorFuzzer
RawParserFuzzer-GetDecoder
RawParserFuzzer-GetDecoder-Decode
RawSpeedFuzzer
@@ -49,3 +101,4 @@ TiffDecoderFuzzer-SrwDecoder
TiffDecoderFuzzer-ThreefrDecoder
TiffParserFuzzer-GetDecoder
TiffParserFuzzer-GetDecoder-Decode
+VC5DecompressorFuzzer
diff --git a/src/external/rawspeed/fuzz/libFuzzer_dummy_main.cpp b/src/external/rawspeed/fuzz/libFuzzer_dummy_main.cpp
index fc6ab6b18..3479d098e 100644
--- a/src/external/rawspeed/fuzz/libFuzzer_dummy_main.cpp
+++ b/src/external/rawspeed/fuzz/libFuzzer_dummy_main.cpp
@@ -18,6 +18,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "rawspeedconfig.h"
#include "io/Buffer.h" // for Buffer
#include "io/FileIOException.h" // for FileIOException
#include "io/FileReader.h" // for FileReader
@@ -25,8 +26,9 @@
#include <cstdlib> // for EXIT_SUCCESS, size_t
#include <iostream> // for operator<<, cout, ostream
#include <memory> // for unique_ptr
+#include <string> // for operator==, string
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#include <omp.h>
#endif
@@ -59,7 +61,7 @@ int main(int argc, char** argv) {
if (1 == argc || (2 == argc && std::string("-help=1") == argv[1]))
return usage();
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
const auto corpusCount = argc - 1;
auto chunkSize = (corpusCount / (10 * omp_get_num_threads()));
if (chunkSize <= 1)
diff --git a/src/external/rawspeed/fuzz/librawspeed/decoders/TiffDecoders/main.cpp b/src/external/rawspeed/fuzz/librawspeed/decoders/TiffDecoders/main.cpp
index f0c45fec6..b2c699fc4 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decoders/TiffDecoders/main.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/decoders/TiffDecoders/main.cpp
@@ -43,11 +43,11 @@
#include "io/Buffer.h" // for Buffer, DataBuffer
#include "metadata/CameraMetaData.h" // for CameraMetaData
#include "parsers/TiffParser.h" // for TiffParser
-#include <algorithm> // for move
#include <cassert> // for assert
#include <cstdint> // for uint8_t
#include <cstdio> // for size_t
#include <memory> // for unique_ptr
+#include <utility> // for move
static const rawspeed::CameraMetaData metadata{};
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/CMakeLists.txt b/src/external/rawspeed/fuzz/librawspeed/decompressors/CMakeLists.txt
index 50bf046ae..92547689f 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/CMakeLists.txt
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/CMakeLists.txt
@@ -20,12 +20,15 @@ set(DECOMPRESSORS
"NikonDecompressor"
"OlympusDecompressor"
"PanasonicDecompressor"
+ "PanasonicDecompressorV5"
"PentaxDecompressor"
+ "PhaseOneDecompressor"
"SamsungV0Decompressor"
"SamsungV1Decompressor"
"SamsungV2Decompressor"
"SonyArw1Decompressor"
"SonyArw2Decompressor"
+ "VC5Decompressor"
)
foreach(decompressor IN LISTS DECOMPRESSORS)
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/Cr2Decompressor.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/Cr2Decompressor.cpp
index f07a791b4..844e6937a 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/Cr2Decompressor.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/Cr2Decompressor.cpp
@@ -18,19 +18,16 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "decompressors/Cr2Decompressor.h" // for Cr2Decompressor
-#include "common/RawImage.h" // for RawImage
-#include "common/RawspeedException.h" // for RawspeedException
-#include "fuzz/Common.h" // for CreateRawImage
-#include "io/Buffer.h" // for Buffer, DataBuffer
-#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for Endianness, Endianness::
-#include <algorithm> // for generate_n, fill_n
-#include <cassert> // for assert
-#include <cstdint> // for uint8_t
-#include <cstdio> // for size_t
-#include <iterator> // for back_insert_iterator
-#include <vector> // for vector
+#include "decompressors/Cr2Decompressor.h"
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "common/RawspeedException.h" // for RawspeedException
+#include "fuzz/Common.h" // for CreateRawImage
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endianness::little
+#include <cassert> // for assert
+#include <cstdint> // for uint8_t
+#include <cstdio> // for size_t
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/CMakeLists.txt b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/CMakeLists.txt
index 9213c2cbc..c6a568577 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/CMakeLists.txt
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/CMakeLists.txt
@@ -4,12 +4,13 @@ add_dependencies(fuzzers HuffmanTableFuzzers)
set(FullDecode true)
set(NoFullDecode false)
-function(add_ht_fuzzer pump decode)
- set(fuzzer "HuffmanTableFuzzer-${pump}-${decode}")
+function(add_ht_solo_fuzzer impl pump decode)
+ set(fuzzer "HuffmanTable${impl}Fuzzer-${pump}-${decode}")
- add_executable(${fuzzer} main.cpp)
+ add_executable(${fuzzer} Solo.cpp)
target_compile_definitions(${fuzzer}
PRIVATE
+ -DIMPL=HuffmanTable${impl}
-DPUMP=${pump}
-DFULLDECODE=${${decode}}
)
@@ -19,11 +20,58 @@ function(add_ht_fuzzer pump decode)
add_dependencies(HuffmanTableFuzzers ${fuzzer})
endfunction()
-set(PUMPS "BitPumpLSB" "BitPumpMSB" "BitPumpMSB16" "BitPumpMSB32" "BitPumpJPEG")
+function(add_ht_dual_fuzzer impl0 impl1 pump decode)
+ set(fuzzer "HuffmanTableFuzzer-${impl0}Vs${impl1}-${pump}-${decode}")
+
+ add_executable(${fuzzer} Dual.cpp)
+ target_compile_definitions(${fuzzer}
+ PRIVATE
+ -DIMPL0=HuffmanTable${impl0}
+ -DIMPL1=HuffmanTable${impl1}
+ -DPUMP=${pump}
+ -DFULLDECODE=${${decode}}
+ )
+
+ add_fuzz_target(${fuzzer})
+
+ add_dependencies(HuffmanTableFuzzers ${fuzzer})
+endfunction()
+
+set(IMPL "LUT" "Lookup" "Tree" "Vector")
+set(PUMPS "BitPumpMSB" "BitPumpMSB32" "BitPumpJPEG")
set(DECODE "FullDecode" "NoFullDecode")
+foreach(impl IN LISTS IMPL)
+ foreach(pump IN LISTS PUMPS)
+ foreach(decode IN LISTS DECODE)
+ add_ht_solo_fuzzer(${impl} ${pump} ${decode})
+ endforeach()
+ endforeach()
+endforeach()
+
+set(ALL_UNIQUE_IMPL_PAIRS)
+foreach(impl0 IN LISTS IMPL)
+ foreach(impl1 IN LISTS IMPL)
+ if("${impl0}" STREQUAL "${impl1}")
+ continue()
+ endif()
+ set(PAIR ${impl0} ${impl1})
+ list(SORT PAIR)
+ string(REPLACE ";" "|" PAIR "${PAIR}")
+ list(APPEND ALL_UNIQUE_IMPL_PAIRS "${PAIR}")
+ endforeach()
+endforeach()
+
+list(REMOVE_DUPLICATES ALL_UNIQUE_IMPL_PAIRS)
+
foreach(pump IN LISTS PUMPS)
foreach(decode IN LISTS DECODE)
- add_ht_fuzzer(${pump} ${decode})
+ foreach(impl IN LISTS ALL_UNIQUE_IMPL_PAIRS)
+ string(REPLACE "|" ";" impl "${impl}")
+ list(GET impl 0 impl0)
+ list(GET impl 1 impl1)
+
+ add_ht_dual_fuzzer(${impl0} ${impl1} ${pump} ${decode})
+ endforeach()
endforeach()
endforeach()
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Common.h b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Common.h
new file mode 100644
index 000000000..ecbe44597
--- /dev/null
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Common.h
@@ -0,0 +1,39 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017-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/Buffer.h" // for Buffer
+#include "io/ByteStream.h" // for ByteStream
+
+template <typename T> static T createHuffmanTable(rawspeed::ByteStream* bs) {
+ T ht;
+
+ // first 16 bytes are consumed as n-codes-per-length
+ const auto count = ht.setNCodesPerLength(bs->getBuffer(16));
+
+ // and then count more bytes consumed as code values
+ ht.setCodeValues(bs->getBuffer(count));
+
+ // and one more byte as 'fixDNGBug16' boolean
+ const auto bb = bs->getBuffer(1);
+ const bool fixDNGBug16 = bb[0] != 0;
+ ht.setup(FULLDECODE, fixDNGBug16);
+
+ return ht;
+}
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Dual.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Dual.cpp
new file mode 100644
index 000000000..af5b91641
--- /dev/null
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Dual.cpp
@@ -0,0 +1,137 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017-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
+*/
+
+#ifndef IMPL0
+#error IMPL0 must be defined to one of rawspeeds pumps
+#endif
+#ifndef IMPL1
+#error IMPL1 must be defined to one of rawspeeds pumps
+#endif
+#ifndef PUMP
+#error PUMP must be defined to one of rawspeeds pumps
+#endif
+#ifndef FULLDECODE
+#error FULLDECODE must be defined as bool
+#endif
+
+#include "common/RawspeedException.h" // for RawspeedException
+#include "decompressors/HuffmanTable.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTable/Common.h" // for createHuffmanTable
+#include "decompressors/HuffmanTableLUT.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTableLookup.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTableTree.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTableVector.h" // IWYU pragma: keep
+#include "io/BitPumpJPEG.h" // IWYU pragma: keep
+#include "io/BitPumpMSB.h" // IWYU pragma: keep
+#include "io/BitPumpMSB32.h" // IWYU pragma: keep
+#include "io/BitStream.h" // for BitStream
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endiannes...
+#include "io/IOException.h" // for IOException
+#include <cassert> // for assert
+#include <cstdint> // for uint8_t
+#include <cstdio> // for size_t
+#include <initializer_list> // IWYU pragma: keep
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ assert(Data);
+
+ try {
+ const rawspeed::Buffer b(Data, Size);
+ const rawspeed::DataBuffer db(b, rawspeed::Endianness::little);
+
+ rawspeed::ByteStream bs0(db);
+ rawspeed::ByteStream bs1(db);
+
+ bool failure0 = false;
+ bool failure1 = false;
+
+ rawspeed::IMPL0 ht0;
+ rawspeed::IMPL1 ht1;
+
+ try {
+ ht0 = createHuffmanTable<rawspeed::IMPL0>(&bs0);
+ } catch (rawspeed::RawspeedException&) {
+ failure0 = true;
+ }
+ try {
+ ht1 = createHuffmanTable<rawspeed::IMPL1>(&bs1);
+ } catch (rawspeed::RawspeedException&) {
+ failure1 = true;
+ }
+
+ // They both should either fail or succeed, else there is a bug.
+ assert(failure0 == failure1);
+
+ // If any failed, we can't continue.
+ if (failure0 || failure1)
+ return 0;
+
+ // should have consumed 16 bytes for n-codes-per-length,
+ // at *least* 1 byte as code value, and 1 byte as 'fixDNGBug16' boolean
+ assert(bs0.getPosition() == bs1.getPosition());
+ assert(bs0.getPosition() >= 18);
+
+ rawspeed::PUMP bits0(bs0);
+ rawspeed::PUMP bits1(bs1);
+
+ while (true) {
+ int decoded0;
+ int decoded1;
+
+ try {
+ decoded0 = ht0.decode<decltype(bits0), FULLDECODE>(bits0);
+ } catch (rawspeed::IOException&) {
+ // For now, let's ignore stream depleteon issues.
+ throw;
+ } catch (rawspeed::RawspeedException&) {
+ failure0 = true;
+ }
+ try {
+ decoded1 = ht1.decode<decltype(bits1), FULLDECODE>(bits1);
+ } catch (rawspeed::IOException&) {
+ // For now, let's ignore stream depleteon issues.
+ throw;
+ } catch (rawspeed::RawspeedException&) {
+ failure1 = true;
+ }
+
+ // They both should either fail or succeed, else there is a bug.
+ assert(failure0 == failure1);
+
+ // If any failed, we can't continue.
+ if (failure0 || failure1)
+ return 0;
+
+ (void)decoded0;
+ (void)decoded1;
+
+ // They both should have decoded the same value.
+ assert(decoded0 == decoded1);
+ }
+ } catch (rawspeed::RawspeedException&) {
+ return 0;
+ }
+
+ __builtin_unreachable();
+}
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/main.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Solo.cpp
index 0d75fd6e6..cd34cc2a9 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/main.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/HuffmanTable/Solo.cpp
@@ -1,7 +1,7 @@
/*
RawSpeed - RAW file decoder.
- Copyright (C) 2017 Roman Lebedev
+ Copyright (C) 2017-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
@@ -18,6 +18,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef IMPL
+#error IMPL must be defined to one of rawspeeds pumps
+#endif
#ifndef PUMP
#error PUMP must be defined to one of rawspeeds pumps
#endif
@@ -25,40 +28,27 @@
#error FULLDECODE must be defined as bool
#endif
-#include "common/RawspeedException.h" // for RawspeedException
-#include "decompressors/HuffmanTable.h" // for HuffmanTable
-#include "io/BitPumpJPEG.h" // IWYU pragma: keep
-#include "io/BitPumpLSB.h" // IWYU pragma: keep
-#include "io/BitPumpMSB.h" // IWYU pragma: keep
-#include "io/BitPumpMSB16.h" // IWYU pragma: keep
-#include "io/BitPumpMSB32.h" // IWYU pragma: keep
-#include "io/BitStream.h" // for BitStream
-#include "io/Buffer.h" // for Buffer, DataBuffer
-#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for Endianness, Endianness::little
-#include <cassert> // for assert
-#include <cstdint> // for uint8_t
-#include <cstdio> // for size_t
+#include "common/RawspeedException.h" // for RawspeedException
+#include "decompressors/HuffmanTable.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTable/Common.h" // for createHuffmanTable
+#include "decompressors/HuffmanTableLUT.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTableLookup.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTableTree.h" // IWYU pragma: keep
+#include "decompressors/HuffmanTableVector.h" // IWYU pragma: keep
+#include "io/BitPumpJPEG.h" // IWYU pragma: keep
+#include "io/BitPumpMSB.h" // IWYU pragma: keep
+#include "io/BitPumpMSB32.h" // IWYU pragma: keep
+#include "io/BitStream.h" // for BitStream
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endiannes...
+#include <cassert> // for assert
+#include <cstdint> // for uint8_t
+#include <cstdio> // for size_t
+#include <initializer_list> // IWYU pragma: keep
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
-static rawspeed::HuffmanTable createHuffmanTable(rawspeed::ByteStream* bs) {
- rawspeed::HuffmanTable ht;
-
- // first 16 bytes are consumed as n-codes-per-length
- const auto count = ht.setNCodesPerLength(bs->getBuffer(16));
-
- // and then count more bytes consumed as code values
- ht.setCodeValues(bs->getBuffer(count));
-
- // and one more byte as 'fixDNGBug16' boolean
- const auto bb = bs->getBuffer(1);
- const bool fixDNGBug16 = bb[0] != 0;
- ht.setup(FULLDECODE, fixDNGBug16);
-
- return ht;
-}
-
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
assert(Data);
@@ -67,13 +57,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
const rawspeed::DataBuffer db(b, rawspeed::Endianness::little);
rawspeed::ByteStream bs(db);
- const rawspeed::HuffmanTable ht = createHuffmanTable(&bs);
+ const rawspeed::IMPL ht = createHuffmanTable<rawspeed::IMPL>(&bs);
// should have consumed 16 bytes for n-codes-per-length,
// at *least* 1 byte as code value, and 1 byte as 'fixDNGBug16' boolean
assert(bs.getPosition() >= 18);
- // FIXME: BitPumpJPEG timeouts
rawspeed::PUMP bits(bs);
while (true)
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/KodakDecompressor.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/KodakDecompressor.cpp
index 957632ed9..9a1b504b4 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/KodakDecompressor.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/KodakDecompressor.cpp
@@ -41,9 +41,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
rawspeed::RawImage mRaw(CreateRawImage(&bs));
+ const bool bps = bs.getU32();
const bool uncorrectedRawValues = bs.getU32();
- rawspeed::KodakDecompressor k(mRaw, bs.getStream(bs.getRemainSize()),
+ rawspeed::KodakDecompressor k(mRaw, bs.getStream(bs.getRemainSize()), bps,
uncorrectedRawValues);
mRaw->createData();
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/NikonDecompressor.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/NikonDecompressor.cpp
index 9ddd4fec2..40115c345 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/NikonDecompressor.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/NikonDecompressor.cpp
@@ -47,9 +47,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
rawspeed::ByteStream metaData = bs.getStream(medataLength);
rawspeed::ByteStream rawData = bs.getStream(bs.getRemainSize());
- rawspeed::NikonDecompressor n(mRaw, bitsPS);
+ rawspeed::NikonDecompressor n(mRaw, metaData, bitsPS);
mRaw->createData();
- n.decompress(metaData, rawData, uncorrectedRawValues);
+ n.decompress(rawData, uncorrectedRawValues);
mRaw->checkMemIsInitialized();
} catch (rawspeed::RawspeedException&) {
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressor.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressor.cpp
index f3de18795..74404ca12 100644
--- a/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressor.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressor.cpp
@@ -42,11 +42,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
rawspeed::RawImage mRaw(CreateRawImage(&bs));
const auto zero_is_not_bad = bs.get<rawspeed::uint32>();
- const auto load_flags = bs.get<rawspeed::uint32>();
+ const auto section_split_offset = bs.get<rawspeed::uint32>();
rawspeed::ByteStream rawData = bs.getStream(bs.getRemainSize());
rawspeed::PanasonicDecompressor p(mRaw, rawData, zero_is_not_bad,
- load_flags);
+ section_split_offset);
mRaw->createData();
p.decompress();
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressorV5.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressorV5.cpp
new file mode 100644
index 000000000..f9fc3cce9
--- /dev/null
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/PanasonicDecompressorV5.cpp
@@ -0,0 +1,56 @@
+/*
+ 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 "decompressors/PanasonicDecompressorV5.h"
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "common/RawspeedException.h" // for RawspeedException
+#include "fuzz/Common.h" // for CreateRawImage
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endianness::little
+#include <cassert> // for assert
+#include <cstdint> // for uint8_t
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ assert(Data);
+
+ try {
+ const rawspeed::Buffer b(Data, Size);
+ const rawspeed::DataBuffer db(b, rawspeed::Endianness::little);
+ rawspeed::ByteStream bs(db);
+
+ rawspeed::RawImage mRaw(CreateRawImage(&bs));
+
+ const auto bps = bs.get<rawspeed::uint32>();
+ rawspeed::ByteStream rawData = bs.getStream(bs.getRemainSize());
+
+ rawspeed::PanasonicDecompressorV5 p(mRaw, rawData, bps);
+ mRaw->createData();
+ p.decompress();
+
+ mRaw->checkMemIsInitialized();
+ } catch (rawspeed::RawspeedException&) {
+ // Exceptions are good, crashes are bad.
+ }
+
+ return 0;
+}
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/PhaseOneDecompressor.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/PhaseOneDecompressor.cpp
new file mode 100644
index 000000000..d8082f99e
--- /dev/null
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/PhaseOneDecompressor.cpp
@@ -0,0 +1,66 @@
+/*
+ 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 "decompressors/PhaseOneDecompressor.h" // for PhaseOneDecompressor
+#include "common/RawImage.h" // for RawImage
+#include "common/RawspeedException.h" // for RawspeedException
+#include "fuzz/Common.h" // for CreateRawImage
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endianness::
+#include <algorithm> // for generate_n
+#include <cassert> // for assert
+#include <cstdint> // for uint8_t
+#include <cstdio> // for size_t
+#include <iterator> // for back_insert_iterator
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ assert(Data);
+
+ try {
+ const rawspeed::Buffer b(Data, Size);
+ const rawspeed::DataBuffer db(b, rawspeed::Endianness::little);
+ rawspeed::ByteStream bs(db);
+
+ rawspeed::RawImage mRaw(CreateRawImage(&bs));
+
+ const auto numStrips = bs.getU32();
+ std::vector<rawspeed::PhaseOneStrip> strips;
+ std::generate_n(std::back_inserter(strips), numStrips,
+ [&bs]() -> rawspeed::PhaseOneStrip {
+ const int n = bs.getU32();
+ const auto stripLen = bs.getU32();
+ return {n, bs.getStream(stripLen)};
+ });
+ assert(strips.size() == numStrips);
+
+ rawspeed::PhaseOneDecompressor f(mRaw, std::move(strips));
+ mRaw->createData();
+ f.decompress();
+
+ mRaw->checkMemIsInitialized();
+ } catch (rawspeed::RawspeedException&) {
+ // Exceptions are good, crashes are bad.
+ }
+
+ return 0;
+}
diff --git a/src/external/rawspeed/fuzz/librawspeed/decompressors/VC5Decompressor.cpp b/src/external/rawspeed/fuzz/librawspeed/decompressors/VC5Decompressor.cpp
new file mode 100644
index 000000000..02d006453
--- /dev/null
+++ b/src/external/rawspeed/fuzz/librawspeed/decompressors/VC5Decompressor.cpp
@@ -0,0 +1,62 @@
+/*
+ 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 "decompressors/VC5Decompressor.h" // for VC5Decompressor
+#include "common/RawImage.h" // for RawImage
+#include "common/RawspeedException.h" // for RawspeedException
+#include "fuzz/Common.h" // for CreateRawImage
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endianne...
+#include <cassert> // for assert
+#include <cstdint> // for uint8_t
+#include <cstdio> // for size_t
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ assert(Data);
+
+ try {
+ const rawspeed::Buffer b(Data, Size);
+ const rawspeed::DataBuffer db(b, rawspeed::Endianness::little);
+ rawspeed::ByteStream bs(db);
+
+ rawspeed::RawImage mRaw(CreateRawImage(&bs));
+ mRaw->whitePoint = bs.getI32();
+
+ const auto offsetX = bs.getU32();
+ const auto offsetY = bs.getU32();
+ const auto width = bs.getU32();
+ const auto height = bs.getU32();
+
+ rawspeed::VC5Decompressor v(bs, mRaw);
+ mRaw->createData();
+ v.decode(offsetX, offsetY, width, height);
+
+ // VC5Decompressor is special
+ // It is expected to be the only DNG tile, and to fill the entire image.
+ mRaw->checkMemIsInitialized();
+ } catch (rawspeed::RawspeedException&) {
+ // Exceptions are good, crashes are bad.
+ }
+
+ return 0;
+}
diff --git a/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.cpp b/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.cpp
index 6b92db812..db4553458 100644
--- a/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.cpp
+++ b/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.cpp
@@ -18,12 +18,15 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "fuzz/Common.h" // for CreateRawImage
+#include "fuzz/Common.h"
+#include "common/Common.h" // for uint32
#include "common/Point.h" // for iPoint2D
-#include "common/RawImage.h" // for RawImage
-#include "common/RawspeedException.h" // for RawspeedException
+#include "common/RawImage.h" // for RawImage, RawImageData, RawIm...
+#include "common/RawspeedException.h" // for ThrowRSE
#include "io/ByteStream.h" // for ByteStream
-#include "metadata/ColorFilterArray.h" // for ColorFilterArray
+#include "io/IOException.h" // for ThrowIOE
+#include "metadata/ColorFilterArray.h" // for ColorFilterArray, CFAColor
+#include <cassert> // for assert
#include <limits> // for numeric_limits
rawspeed::RawImage CreateRawImage(rawspeed::ByteStream* bs) {
diff --git a/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.h b/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.h
index 665ca7124..e9d3ccdd5 100644
--- a/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.h
+++ b/src/external/rawspeed/fuzz/librawspeed/fuzz/Common.h
@@ -19,8 +19,11 @@
*/
#include "common/RawImage.h" // for RawImage
-#include "io/ByteStream.h" // for ByteStream
#include "metadata/ColorFilterArray.h" // for ColorFilterArray
+namespace rawspeed {
+class ByteStream;
+} // namespace rawspeed
+
rawspeed::RawImage CreateRawImage(rawspeed::ByteStream* bs);
rawspeed::ColorFilterArray CreateCFA(rawspeed::ByteStream* bs);
diff --git a/src/external/rawspeed/src/CMakeLists.txt b/src/external/rawspeed/src/CMakeLists.txt
index a57f01b00..1feedc6c3 100644
--- a/src/external/rawspeed/src/CMakeLists.txt
+++ b/src/external/rawspeed/src/CMakeLists.txt
@@ -1,14 +1,10 @@
-add_library(rawspeed STATIC)
-
-include(src-dependencies)
-
include(memory-align-alloc)
include(thread-local)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/rawspeedconfig.h")
target_include_directories(rawspeed PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")
-target_include_directories(rawspeed SYSTEM PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/external/")
+add_subdirectory(external)
add_subdirectory(librawspeed)
diff --git a/src/external/rawspeed/src/config.h.in b/src/external/rawspeed/src/config.h.in
index adde14a4b..4faf27997 100644
--- a/src/external/rawspeed/src/config.h.in
+++ b/src/external/rawspeed/src/config.h.in
@@ -30,6 +30,8 @@
#cmakedefine HAVE_PTHREAD
+#cmakedefine HAVE_OPENMP
+
#cmakedefine HAVE_PUGIXML
#cmakedefine HAVE_ZLIB
diff --git a/src/external/rawspeed/src/external/CMakeLists.txt b/src/external/rawspeed/src/external/CMakeLists.txt
new file mode 100644
index 000000000..8a4d6907d
--- /dev/null
+++ b/src/external/rawspeed/src/external/CMakeLists.txt
@@ -0,0 +1,12 @@
+target_include_directories(rawspeed SYSTEM PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+
+FILE(GLOB SOURCES
+ AddressSanitizer.h
+ MemorySanitizer.h
+ ThreadSafetyAnalysis.h
+ gopro/vc5/table17.inc
+)
+
+target_sources(rawspeed PRIVATE
+ ${SOURCES}
+)
diff --git a/src/external/rawspeed/src/external/gopro/vc5/table17.inc b/src/external/rawspeed/src/external/gopro/vc5/table17.inc
new file mode 100644
index 000000000..4a6255426
--- /dev/null
+++ b/src/external/rawspeed/src/external/gopro/vc5/table17.inc
@@ -0,0 +1,291 @@
+// Taken from https://raw.githubusercontent.com/gopro/gpr/d2d78d1b236a278a13ed5abee6870af2b490c89f/source/lib/vc5_common/table17.inc
+/*! @file bitstream.h
+ *
+ * @brief Declaration of the bitstream data structure.
+ *
+ * @version 1.0.0
+ *
+ * (C) Copyright 2018 GoPro Inc (http://gopro.com/).
+ *
+ * Licensed under either:
+ * - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
+ * - MIT license, http://opensource.org/licenses/MIT
+ * at your option.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+RLVTABLE(264) table17 =
+{
+ 264,
+ {
+ {1, 0x00000000, 1, 0}, // m0
+ {2, 0x00000002, 1, 1}, // m1
+ {3, 0x00000007, 1, 2}, // m2
+ {5, 0x00000019, 1, 3}, // m3
+ {6, 0x00000030, 1, 4}, // m4
+ {6, 0x00000036, 1, 5}, // m5
+ {7, 0x0000006F, 1, 8}, // m8
+ {7, 0x00000063, 1, 6}, // m6
+ {7, 0x00000069, 12, 0}, // z12
+ {7, 0x0000006B, 1, 7}, // m7
+ {8, 0x000000D1, 20, 0}, // z20
+ {8, 0x000000D4, 1, 9}, // m9
+ {8, 0x000000DC, 1, 10}, // m10
+ {9, 0x00000189, 1, 11}, // m11
+ {9, 0x0000018A, 32, 0}, // z32
+ {9, 0x000001A0, 1, 12}, // m12
+ {9, 0x000001AB, 1, 13}, // m13
+ {10, 0x00000377, 1, 18}, // m18
+ {10, 0x00000310, 1, 14}, // m14
+ {10, 0x00000316, 1, 15}, // m15
+ {10, 0x00000343, 60, 0}, // z60
+ {10, 0x00000354, 1, 16}, // m16
+ {10, 0x00000375, 1, 17}, // m17
+ {11, 0x00000623, 1, 19}, // m19
+ {11, 0x00000684, 1, 20}, // m20
+ {11, 0x00000685, 100, 0}, // z100
+ {11, 0x000006AB, 1, 21}, // m21
+ {11, 0x000006EC, 1, 22}, // m22
+ {12, 0x00000DDB, 1, 29}, // m29
+ {12, 0x00000C5C, 1, 24}, // m24
+ {12, 0x00000C5E, 1, 25}, // m25
+ {12, 0x00000C44, 1, 23}, // m23
+ {12, 0x00000D55, 1, 26}, // m26
+ {12, 0x00000DD1, 1, 27}, // m27
+ {12, 0x00000DD3, 1, 28}, // m28
+ {13, 0x00001BB5, 1, 35}, // m35
+ {13, 0x0000188B, 1, 30}, // m30
+ {13, 0x000018BB, 1, 31}, // m31
+ {13, 0x000018BF, 180, 0}, // z180
+ {13, 0x00001AA8, 1, 32}, // m32
+ {13, 0x00001BA0, 1, 33}, // m33
+ {13, 0x00001BA5, 320, 0}, // z320
+ {13, 0x00001BA4, 1, 34}, // m34
+ {14, 0x00003115, 1, 36}, // m36
+ {14, 0x00003175, 1, 37}, // m37
+ {14, 0x0000317D, 1, 38}, // m38
+ {14, 0x00003553, 1, 39}, // m39
+ {14, 0x00003768, 1, 40}, // m40
+ {15, 0x00006E87, 1, 46}, // m46
+ {15, 0x00006ED3, 1, 47}, // m47
+ {15, 0x000062E8, 1, 42}, // m42
+ {15, 0x000062F8, 1, 43}, // m43
+ {15, 0x00006228, 1, 41}, // m41
+ {15, 0x00006AA4, 1, 44}, // m44
+ {15, 0x00006E85, 1, 45}, // m45
+ {16, 0x0000C453, 1, 48}, // m48
+ {16, 0x0000C5D3, 1, 49}, // m49
+ {16, 0x0000C5F3, 1, 50}, // m50
+ {16, 0x0000DDA4, 1, 53}, // m53
+ {16, 0x0000DD08, 1, 51}, // m51
+ {16, 0x0000DD0C, 1, 52}, // m52
+ {17, 0x0001BB4B, 1, 61}, // m61
+ {17, 0x0001BB4A, 1, 60}, // m60
+ {17, 0x00018BA5, 1, 55}, // m55
+ {17, 0x00018BE5, 1, 56}, // m56
+ {17, 0x0001AA95, 1, 57}, // m57
+ {17, 0x0001AA97, 1, 58}, // m58
+ {17, 0x000188A4, 1, 54}, // m54
+ {17, 0x0001BA13, 1, 59}, // m59
+ {18, 0x00031748, 1, 62}, // m62
+ {18, 0x000317C8, 1, 63}, // m63
+ {18, 0x00035528, 1, 64}, // m64
+ {18, 0x0003552C, 1, 65}, // m65
+ {18, 0x00037424, 1, 66}, // m66
+ {18, 0x00037434, 1, 67}, // m67
+ {18, 0x00037436, 1, 68}, // m68
+ {19, 0x00062294, 1, 69}, // m69
+ {19, 0x00062E92, 1, 70}, // m70
+ {19, 0x00062F92, 1, 71}, // m71
+ {19, 0x0006AA52, 1, 72}, // m72
+ {19, 0x0006AA5A, 1, 73}, // m73
+ {19, 0x0006E86A, 1, 75}, // m75
+ {19, 0x0006E86E, 1, 76}, // m76
+ {19, 0x0006E84A, 1, 74}, // m74
+ {20, 0x000C452A, 1, 77}, // m77
+ {20, 0x000C5D27, 1, 78}, // m78
+ {20, 0x000C5F26, 1, 79}, // m79
+ {20, 0x000D54A6, 1, 80}, // m80
+ {20, 0x000D54B6, 1, 81}, // m81
+ {20, 0x000DD096, 1, 82}, // m82
+ {20, 0x000DD0D6, 1, 83}, // m83
+ {20, 0x000DD0DE, 1, 84}, // m84
+ {21, 0x00188A56, 1, 85}, // m85
+ {21, 0x0018BA4D, 1, 86}, // m86
+ {21, 0x0018BE4E, 1, 87}, // m87
+ {21, 0x0018BE4F, 1, 88}, // m88
+ {21, 0x001AA96E, 1, 89}, // m89
+ {21, 0x001BA12E, 1, 90}, // m90
+ {21, 0x001BA12F, 1, 91}, // m91
+ {21, 0x001BA1AF, 1, 92}, // m92
+ {21, 0x001BA1BF, 1, 93}, // m93
+ {22, 0x0037435D, 1, 99}, // m99
+ {22, 0x0037437D, 1, 100}, // m100
+ {22, 0x00317498, 1, 94}, // m94
+ {22, 0x0035529C, 1, 95}, // m95
+ {22, 0x0035529D, 1, 96}, // m96
+ {22, 0x003552DE, 1, 97}, // m97
+ {22, 0x003552DF, 1, 98}, // m98
+ {23, 0x0062E933, 1, 102}, // m102
+ {23, 0x0062295D, 1, 101}, // m101
+ {23, 0x006AA53D, 1, 103}, // m103
+ {23, 0x006AA53F, 1, 105}, // m105
+ {23, 0x006AA53E, 1, 104}, // m104
+ {23, 0x006E86B9, 1, 106}, // m106
+ {23, 0x006E86F8, 1, 107}, // m107
+ {24, 0x00D54A79, 1, 111}, // m111
+ {24, 0x00C5D265, 1, 109}, // m109
+ {24, 0x00C452B8, 1, 108}, // m108
+ {24, 0x00DD0D71, 1, 113}, // m113
+ {24, 0x00D54A78, 1, 110}, // m110
+ {24, 0x00DD0D70, 1, 112}, // m112
+ {24, 0x00DD0DF2, 1, 114}, // m114
+ {24, 0x00DD0DF3, 1, 115}, // m115
+ {25, 0x0188A5F6, 1, 225}, // m225
+ {25, 0x0188A5F5, 1, 189}, // m189
+ {25, 0x0188A5F4, 1, 188}, // m188
+ {25, 0x0188A5F3, 1, 203}, // m203
+ {25, 0x0188A5F2, 1, 202}, // m202
+ {25, 0x0188A5F1, 1, 197}, // m197
+ {25, 0x0188A5F0, 1, 207}, // m207
+ {25, 0x0188A5EF, 1, 169}, // m169
+ {25, 0x0188A5EE, 1, 223}, // m223
+ {25, 0x0188A5ED, 1, 159}, // m159
+ {25, 0x0188A5AA, 1, 235}, // m235
+ {25, 0x0188A5E3, 1, 152}, // m152
+ {25, 0x0188A5DF, 1, 192}, // m192
+ {25, 0x0188A589, 1, 179}, // m179
+ {25, 0x0188A5DD, 1, 201}, // m201
+ {25, 0x0188A578, 1, 172}, // m172
+ {25, 0x0188A5E0, 1, 149}, // m149
+ {25, 0x0188A588, 1, 178}, // m178
+ {25, 0x0188A5D6, 1, 120}, // m120
+ {25, 0x0188A5DB, 1, 219}, // m219
+ {25, 0x0188A5E1, 1, 150}, // m150
+ {25, 0x0188A587, 1, 127}, // m127
+ {25, 0x0188A59A, 1, 211}, // m211
+ {25, 0x0188A5C4, 1, 125}, // m125
+ {25, 0x0188A5EC, 1, 158}, // m158
+ {25, 0x0188A586, 1, 247}, // m247
+ {25, 0x0188A573, 1, 238}, // m238
+ {25, 0x0188A59C, 1, 163}, // m163
+ {25, 0x0188A5C8, 1, 228}, // m228
+ {25, 0x0188A5FB, 1, 183}, // m183
+ {25, 0x0188A5A1, 1, 217}, // m217
+ {25, 0x0188A5EB, 1, 168}, // m168
+ {25, 0x0188A5A8, 1, 122}, // m122
+ {25, 0x0188A584, 1, 128}, // m128
+ {25, 0x0188A5D2, 1, 249}, // m249
+ {25, 0x0188A599, 1, 187}, // m187
+ {25, 0x0188A598, 1, 186}, // m186
+ {25, 0x0188A583, 1, 136}, // m136
+ {25, 0x018BA4C9, 1, 181}, // m181
+ {25, 0x0188A5D0, 1, 255}, // m255
+ {25, 0x0188A594, 1, 230}, // m230
+ {25, 0x0188A582, 1, 135}, // m135
+ {25, 0x0188A5CB, 1, 233}, // m233
+ {25, 0x0188A5D8, 1, 222}, // m222
+ {25, 0x0188A5E7, 1, 145}, // m145
+ {25, 0x0188A581, 1, 134}, // m134
+ {25, 0x0188A5EA, 1, 167}, // m167
+ {25, 0x0188A5A9, 1, 248}, // m248
+ {25, 0x0188A5A6, 1, 209}, // m209
+ {25, 0x0188A580, 1, 243}, // m243
+ {25, 0x0188A5A0, 1, 216}, // m216
+ {25, 0x0188A59D, 1, 164}, // m164
+ {25, 0x0188A5C3, 1, 140}, // m140
+ {25, 0x0188A57F, 1, 157}, // m157
+ {25, 0x0188A5C0, 1, 239}, // m239
+ {25, 0x0188A5DE, 1, 191}, // m191
+ {25, 0x0188A5D4, 1, 251}, // m251
+ {25, 0x0188A57E, 1, 156}, // m156
+ {25, 0x0188A5C2, 1, 139}, // m139
+ {25, 0x0188A592, 1, 242}, // m242
+ {25, 0x0188A5CD, 1, 133}, // m133
+ {25, 0x0188A57D, 1, 162}, // m162
+ {25, 0x0188A5A3, 1, 213}, // m213
+ {25, 0x0188A5E8, 1, 165}, // m165
+ {25, 0x0188A5A2, 1, 212}, // m212
+ {25, 0x0188A57C, 1, 227}, // m227
+ {25, 0x0188A58E, 1, 198}, // m198
+ {25, 0x0188A5B3, 1, 236}, // m236
+ {25, 0x0188A5B2, 1, 234}, // m234
+ {25, 0x0188A5B1, 1, 117}, // m117
+ {25, 0x0188A5B0, 1, 215}, // m215
+ {25, 0x0188A5AF, 1, 124}, // m124
+ {25, 0x0188A5AE, 1, 123}, // m123
+ {25, 0x0188A5AD, 1, 254}, // m254
+ {25, 0x0188A5AC, 1, 253}, // m253
+ {25, 0x0188A5AB, 1, 148}, // m148
+ {25, 0x0188A5DA, 1, 218}, // m218
+ {25, 0x0188A5E4, 1, 146}, // m146
+ {25, 0x0188A5E5, 1, 147}, // m147
+ {25, 0x0188A5D9, 1, 224}, // m224
+ {25, 0x0188A5B5, 1, 143}, // m143
+ {25, 0x0188A5BC, 1, 184}, // m184
+ {25, 0x0188A5BD, 1, 185}, // m185
+ {25, 0x0188A5E9, 1, 166}, // m166
+ {25, 0x0188A5CC, 1, 132}, // m132
+ {25, 0x0188A585, 1, 129}, // m129
+ {25, 0x0188A5D3, 1, 250}, // m250
+ {25, 0x0188A5E2, 1, 151}, // m151
+ {25, 0x0188A595, 1, 119}, // m119
+ {25, 0x0188A596, 1, 193}, // m193
+ {25, 0x0188A5B8, 1, 176}, // m176
+ {25, 0x0188A590, 1, 245}, // m245
+ {25, 0x0188A5C9, 1, 229}, // m229
+ {25, 0x0188A5A4, 1, 206}, // m206
+ {25, 0x0188A5E6, 1, 144}, // m144
+ {25, 0x0188A5A5, 1, 208}, // m208
+ {25, 0x0188A5CE, 1, 137}, // m137
+ {25, 0x0188A5BF, 1, 241}, // m241
+ {25, 0x0188A572, 1, 237}, // m237
+ {25, 0x0188A59B, 1, 190}, // m190
+ {25, 0x0188A5BE, 1, 240}, // m240
+ {25, 0x0188A5C7, 1, 131}, // m131
+ {25, 0x0188A5CA, 1, 232}, // m232
+ {25, 0x0188A5D5, 1, 252}, // m252
+ {25, 0x0188A57B, 1, 171}, // m171
+ {25, 0x0188A58D, 1, 205}, // m205
+ {25, 0x0188A58C, 1, 204}, // m204
+ {25, 0x0188A58B, 1, 118}, // m118
+ {25, 0x0188A58A, 1, 214}, // m214
+ {25, 0x018BA4C8, 1, 180}, // m180
+ {25, 0x0188A5C5, 1, 126}, // m126
+ {25, 0x0188A5FA, 1, 182}, // m182
+ {25, 0x0188A5BB, 1, 175}, // m175
+ {25, 0x0188A5C1, 1, 141}, // m141
+ {25, 0x0188A5CF, 1, 138}, // m138
+ {25, 0x0188A5B9, 1, 177}, // m177
+ {25, 0x0188A5B6, 1, 153}, // m153
+ {25, 0x0188A597, 1, 194}, // m194
+ {25, 0x0188A5FE, 1, 160}, // m160
+ {25, 0x0188A5D7, 1, 121}, // m121
+ {25, 0x0188A5BA, 1, 174}, // m174
+ {25, 0x0188A591, 1, 246}, // m246
+ {25, 0x0188A5C6, 1, 130}, // m130
+ {25, 0x0188A5DC, 1, 200}, // m200
+ {25, 0x0188A57A, 1, 170}, // m170
+ {25, 0x0188A59F, 1, 221}, // m221
+ {25, 0x0188A5F9, 1, 196}, // m196
+ {25, 0x0188A5B4, 1, 142}, // m142
+ {25, 0x0188A5A7, 1, 210}, // m210
+ {25, 0x0188A58F, 1, 199}, // m199
+ {25, 0x0188A5FD, 1, 155}, // m155
+ {25, 0x0188A5B7, 1, 154}, // m154
+ {25, 0x0188A593, 1, 244}, // m244
+ {25, 0x0188A59E, 1, 220}, // m220
+ {25, 0x0188A5F8, 1, 195}, // m195
+ {25, 0x0188A5FF, 1, 161}, // m161
+ {25, 0x0188A5FC, 1, 231}, // m231
+ {25, 0x0188A579, 1, 173}, // m173
+ {25, 0x0188A5F7, 1, 226}, // m226
+ {26, 0x03114BA2, 1, 116}, // m116
+ {26, 0x03114BA3, 0, 1}, // c256
+ }
+};
diff --git a/src/external/rawspeed/src/librawspeed/common/Array2DRef.h b/src/external/rawspeed/src/librawspeed/common/Array2DRef.h
new file mode 100644
index 000000000..ec3a6e16f
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/common/Array2DRef.h
@@ -0,0 +1,87 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2018 Stefan Löffler
+ 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
+*/
+
+#pragma once
+
+#include <cassert> // for assert
+#include <type_traits>
+#include <vector> // for vector
+
+namespace rawspeed {
+
+template <class T> class Array2DRef {
+ int _pitch = 0;
+ T* _data = nullptr;
+
+ friend Array2DRef<const T>; // We need to be able to convert to const version.
+
+public:
+ using value_type = T;
+ using cvless_value_type = typename std::remove_cv<value_type>::type;
+
+ int width = 0, height = 0;
+
+ Array2DRef() = default;
+
+ Array2DRef(T* data, int dataWidth, int dataHeight, int dataPitch = 0);
+
+ // Conversion from Array2DRef<T> to Array2DRef<const T>.
+ template <class T2, typename = std::enable_if_t<std::is_same<
+ typename std::remove_const<T>::type, T2>::value>>
+ Array2DRef(Array2DRef<T2> RHS) { // NOLINT google-explicit-constructor
+ _data = RHS._data;
+ _pitch = RHS._pitch;
+ width = RHS.width;
+ height = RHS.height;
+ }
+
+ template <typename AllocatorType =
+ typename std::vector<cvless_value_type>::allocator_type>
+ static Array2DRef<T>
+ create(std::vector<cvless_value_type, AllocatorType>* storage, int width,
+ int height) {
+ storage->resize(width * height);
+ return {storage->data(), width, height};
+ }
+
+ inline T& operator()(int x, int y) const;
+};
+
+template <class T>
+Array2DRef<T>::Array2DRef(T* data, const int dataWidth, const int dataHeight,
+ const int dataPitch /* = 0 */)
+ : _data(data), width(dataWidth), height(dataHeight) {
+ assert(width >= 0);
+ assert(height >= 0);
+ _pitch = (dataPitch == 0 ? dataWidth : dataPitch);
+}
+
+template <class T>
+T& Array2DRef<T>::operator()(const int x, const int y) const {
+ assert(_data);
+ assert(x >= 0);
+ assert(y >= 0);
+ assert(x < width);
+ assert(y < height);
+ return _data[y * _pitch + x];
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/common/CMakeLists.txt b/src/external/rawspeed/src/librawspeed/common/CMakeLists.txt
index 495e8eeb7..cd984a0bf 100644
--- a/src/external/rawspeed/src/librawspeed/common/CMakeLists.txt
+++ b/src/external/rawspeed/src/librawspeed/common/CMakeLists.txt
@@ -1,7 +1,11 @@
FILE(GLOB SOURCES
+ "Array2DRef.h"
+ "ChecksumFile.cpp"
+ "ChecksumFile.h"
"Common.cpp"
"Common.h"
"Cpuid.cpp"
+ "DefaultInitAllocatorAdaptor.h"
"DngOpcodes.cpp"
"DngOpcodes.h"
"ErrorLog.cpp"
@@ -10,6 +14,7 @@ FILE(GLOB SOURCES
"Memory.h"
"Mutex.h"
"NORangesSet.h"
+ "Optional.h"
"Point.h"
"Range.h"
"RawImage.cpp"
@@ -17,6 +22,7 @@ FILE(GLOB SOURCES
"RawImageDataFloat.cpp"
"RawImageDataU16.cpp"
"RawspeedException.h"
+ "SimpleLUT.h"
"Spline.h"
"TableLookUp.cpp"
"TableLookUp.h"
diff --git a/src/external/rawspeed/src/librawspeed/common/ChecksumFile.cpp b/src/external/rawspeed/src/librawspeed/common/ChecksumFile.cpp
new file mode 100644
index 000000000..144e8c5fd
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/common/ChecksumFile.cpp
@@ -0,0 +1,94 @@
+/*
+ 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/ChecksumFile.h"
+#include "common/Common.h" // for splitString
+#include "common/RawspeedException.h" // for ThrowRSE
+#include "io/Buffer.h" // for Buffer
+#include "io/FileReader.h" // for FileReader
+#include <cassert> // for assert
+#include <memory> // for unique_ptr
+#include <string> // for string, allocator, operator+
+#include <vector> // for vector
+
+namespace rawspeed {
+
+namespace {
+
+// The lenght of the sha1 digest (160-bit, 40 hexadecimal chars).
+constexpr auto Sha1CheckSumLength = 40;
+// The separator after the digest and before filename.
+// Should be either " " or " b".
+constexpr auto CheckSumSeparatorWidth = 2;
+
+ChecksumFileEntry ParseChecksumFileLine(const std::string& Line,
+ const std::string& RootDir) {
+ ChecksumFileEntry Entry;
+
+ // We are just assuming that the checksum file is correct and valid.
+ // It is up to user to validate it first (via actually running `sha1sum -c`).
+
+ static constexpr auto Offset = Sha1CheckSumLength + CheckSumSeparatorWidth;
+
+ if (Line.size() <= Offset)
+ ThrowRSE("Malformed checksum line: \"%s\"", Line.c_str());
+
+ Entry.RelFileName = Line.substr(Offset);
+ assert(!Entry.RelFileName.empty());
+ assert(Entry.RelFileName.back() != '\n');
+
+ Entry.FullFileName = RootDir + "/" + Entry.RelFileName;
+
+ return Entry;
+}
+
+} // namespace
+
+std::vector<ChecksumFileEntry>
+ParseChecksumFileContent(const std::string& ChecksumFileContent,
+ const std::string& RootDir) {
+ std::vector<ChecksumFileEntry> Listing;
+
+ const std::vector<std::string> Lines = splitString(ChecksumFileContent, '\n');
+
+ Listing.reserve(Lines.size());
+
+ for (const auto& Line : Lines) {
+ assert(!Line.empty());
+ Listing.emplace_back(ParseChecksumFileLine(Line, RootDir));
+ }
+
+ return Listing;
+}
+
+std::vector<ChecksumFileEntry>
+ReadChecksumFile(const std::string& RootDir,
+ const std::string& ChecksumFileBasename) {
+ const std::string ChecksumFileName = RootDir + "/" + ChecksumFileBasename;
+ FileReader FR(ChecksumFileName.c_str());
+
+ std::unique_ptr<const Buffer> buf = FR.readFile();
+ const std::string ChecksumFileContent(
+ reinterpret_cast<const char*>(buf->begin()), buf->getSize());
+
+ return ParseChecksumFileContent(ChecksumFileContent, RootDir);
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/common/ChecksumFile.h b/src/external/rawspeed/src/librawspeed/common/ChecksumFile.h
new file mode 100644
index 000000000..79bed10a4
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/common/ChecksumFile.h
@@ -0,0 +1,41 @@
+/*
+ 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
+*/
+
+#pragma once
+
+#include <string> // for string
+#include <vector> // for vector
+
+namespace rawspeed {
+
+struct ChecksumFileEntry {
+ std::string FullFileName;
+ std::string RelFileName;
+};
+
+std::vector<ChecksumFileEntry>
+ParseChecksumFileContent(const std::string& ChecksumFileContent,
+ const std::string& RootDir);
+
+std::vector<ChecksumFileEntry>
+ReadChecksumFile(const std::string& RootDir,
+ const std::string& ChecksumFileBasename = "filelist.sha1");
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/common/Common.h b/src/external/rawspeed/src/librawspeed/common/Common.h
index 9af437c5b..677947673 100644
--- a/src/external/rawspeed/src/librawspeed/common/Common.h
+++ b/src/external/rawspeed/src/librawspeed/common/Common.h
@@ -22,12 +22,14 @@
#include "rawspeedconfig.h"
+#include <algorithm> // IWYU pragma: keep
#include <cassert> // for assert
+#include <climits> // for CHAR_BIT
#include <cstdint> // for uintptr_t
-#include <cstring> // for memcpy, size_t
+#include <cstring> // for size_t, memcpy
#include <initializer_list> // for initializer_list
#include <string> // for string
-#include <type_traits> // for enable_if, is_pointer
+#include <type_traits> // for enable_if, is_pointer, is_signed, is_uns...
#include <vector> // for vector
extern "C" int rawspeed_get_number_of_processor_cores();
@@ -73,10 +75,25 @@ template <typename T> inline constexpr bool isPowerOfTwo(T val) {
}
constexpr inline size_t __attribute__((const))
+roundToMultiple(size_t value, size_t multiple, bool roundDown) {
+ if ((multiple == 0) || (value % multiple == 0))
+ return value;
+ // Drop remainder.
+ size_t roundedDown = value - (value % multiple);
+ if (roundDown) // If we were rounding down, then that's it.
+ return roundedDown;
+ // Else, just add one multiple.
+ return roundedDown + multiple;
+}
+
+constexpr inline size_t __attribute__((const))
+roundDown(size_t value, size_t multiple) {
+ return roundToMultiple(value, multiple, /*roundDown=*/true);
+}
+
+constexpr inline size_t __attribute__((const))
roundUp(size_t value, size_t multiple) {
- return ((multiple == 0) || (value % multiple == 0))
- ? value
- : value + multiple - (value % multiple);
+ return roundToMultiple(value, multiple, /*roundDown=*/false);
}
constexpr inline size_t __attribute__((const))
@@ -122,13 +139,34 @@ inline uint32 getThreadCount()
#endif
}
-// clampBits clamps the given int to the range 0 .. 2^n-1, with n <= 16
-inline ushort16 __attribute__((const)) clampBits(int x, uint32 n) {
- assert(n <= 16);
- const int tmp = (1 << n) - 1;
- x = x < 0 ? 0 : x;
- x = x > tmp ? tmp : x;
- return x;
+// Clamps the given unsigned value to the range 0 .. 2^n-1, with n <= 16
+template <class T>
+inline constexpr __attribute__((const)) ushort16 clampBits(
+ T value, unsigned int nBits,
+ typename std::enable_if<std::is_unsigned<T>::value>::type* /*unused*/ =
+ nullptr) {
+ // We expect to produce ushort16.
+ assert(nBits <= 16);
+ // Check that the clamp is not a no-op. Not of ushort16 to 16 bits e.g.
+ // (Well, not really, if we are called from clampBits<signed>, it's ok..).
+ constexpr auto BitWidthOfT = CHAR_BIT * sizeof(T);
+ (void)BitWidthOfT;
+ assert(BitWidthOfT > nBits); // If nBits >= BitWidthOfT, then shift is UB.
+ const T maxVal = (T(1) << nBits) - T(1);
+ return std::min(value, maxVal);
+}
+
+// Clamps the given signed value to the range 0 .. 2^n-1, with n <= 16
+template <typename T>
+inline constexpr ushort16 __attribute__((const))
+clampBits(T value, unsigned int nBits,
+ typename std::enable_if<std::is_signed<T>::value>::type* /*unused*/ =
+ nullptr) {
+ // If the value is negative, clamp it to zero.
+ value = std::max(value, T(0));
+ // Now, let the unsigned case clamp to the upper limit.
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return clampBits<UnsignedT>(value, nBits);
}
// Trim both leading and trailing spaces from the string
diff --git a/src/external/rawspeed/src/librawspeed/common/DefaultInitAllocatorAdaptor.h b/src/external/rawspeed/src/librawspeed/common/DefaultInitAllocatorAdaptor.h
new file mode 100644
index 000000000..910f9adfe
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/common/DefaultInitAllocatorAdaptor.h
@@ -0,0 +1,101 @@
+/*
+ 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
+*/
+
+#pragma once
+
+#include <memory>
+#include <type_traits>
+
+namespace rawspeed {
+
+template <typename T, typename ActualAllocator = std::allocator<T>,
+ typename = std::enable_if_t<std::is_pod<T>::value>>
+class DefaultInitAllocatorAdaptor {
+public:
+ using allocator_traits = std::allocator_traits<ActualAllocator>;
+
+ using value_type = typename allocator_traits::value_type;
+ using pointer = typename allocator_traits::pointer;
+ using const_pointer = typename allocator_traits::const_pointer;
+ using size_type = typename allocator_traits::size_type;
+ using difference_type = typename allocator_traits::difference_type;
+
+ static_assert(std::is_same<T, value_type>::value, "");
+
+ template <class To> struct rebind {
+ using other = DefaultInitAllocatorAdaptor<
+ To, typename allocator_traits::template rebind_alloc<To>>;
+ };
+
+ using allocator_type =
+ typename allocator_traits::template rebind_alloc<value_type>;
+
+ allocator_type allocator;
+
+ const allocator_type& get_allocator() const noexcept { return allocator; }
+
+ DefaultInitAllocatorAdaptor() noexcept = default;
+
+ explicit DefaultInitAllocatorAdaptor(
+ const allocator_type& allocator_) noexcept
+ : allocator(allocator_) {}
+
+ template <class To>
+ explicit DefaultInitAllocatorAdaptor(
+ const DefaultInitAllocatorAdaptor<
+ To, typename allocator_traits::template rebind_alloc<To>>&
+ allocator_) noexcept
+ : allocator(allocator_.get_allocator()) {}
+
+ pointer allocate(size_type n, const void* hint = nullptr) {
+ return allocator.allocate(n, hint);
+ }
+
+ void deallocate(pointer p, size_type n) noexcept {
+ allocator.deallocate(p, n);
+ }
+
+ template <typename U>
+ void
+ construct(U* ptr) noexcept(std::is_nothrow_default_constructible<U>::value) {
+ ::new (static_cast<void*>(ptr)) U; // start the life-time, but do not init.
+ }
+
+ using propagate_on_container_copy_assignment =
+ typename allocator_traits::propagate_on_container_copy_assignment;
+ using propagate_on_container_move_assignment =
+ typename allocator_traits::propagate_on_container_move_assignment;
+ using propagate_on_container_swap =
+ typename allocator_traits::propagate_on_container_swap;
+};
+
+template <typename T0, typename A0, typename T1, typename A1>
+bool operator==(DefaultInitAllocatorAdaptor<T0, A0> const& x,
+ DefaultInitAllocatorAdaptor<T1, A1> const& y) noexcept {
+ return x.get_allocator() == y.get_allocator();
+}
+
+template <typename T0, typename A0, typename T1, typename A1>
+bool operator!=(DefaultInitAllocatorAdaptor<T0, A0> const& x,
+ DefaultInitAllocatorAdaptor<T1, A1> const& y) noexcept {
+ return !(x == y);
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/common/DngOpcodes.cpp b/src/external/rawspeed/src/librawspeed/common/DngOpcodes.cpp
index 049ce3d3c..747027f28 100644
--- a/src/external/rawspeed/src/librawspeed/common/DngOpcodes.cpp
+++ b/src/external/rawspeed/src/librawspeed/common/DngOpcodes.cpp
@@ -321,9 +321,9 @@ public:
// Create lookup
lookup.resize(65536);
- for (auto i = 0U; i < lookup.size(); ++i) {
+ for (auto i = 0UL; i < lookup.size(); ++i) {
double val = polynomial[0];
- for (auto j = 1U; j < polynomial.size(); ++j)
+ for (auto j = 1UL; j < polynomial.size(); ++j)
val += polynomial[j] * pow(i / 65536.0, j);
lookup[i] = (clampBits(static_cast<int>(val * 65535.5), 16));
}
@@ -433,11 +433,13 @@ public:
template <typename S>
class DngOpcodes::ScalePerRowOrCol final : public DeltaRowOrCol<S> {
// We have pixel value in range of [0..65535]. We scale by float X.
- // For this to generate a value within the same range , the scale X needs
- // to be in the range [0..65535]. Since the offset is multiplied
+ // For this to generate a value within the same range, the scale X needs
+ // to be in the range [0..65535]. However, we are operating with 32-bit
+ // signed integer space, so the new value can not be larger than 2^31,
+ // else we'd have signed integer overflow. Since the offset is multiplied
// by f2iScale before applying, we need to divide by f2iScale here.
- // So the maxLimit has the same value as absLimit for OffsetPerRowOrCol.
static constexpr const double minLimit = 0.0;
+ static constexpr int rounding = 512;
const double maxLimit;
bool valueIsOk(float value) final {
@@ -447,7 +449,8 @@ class DngOpcodes::ScalePerRowOrCol final : public DeltaRowOrCol<S> {
public:
explicit ScalePerRowOrCol(const RawImage& ri, ByteStream* bs)
: DeltaRowOrCol<S>(ri, bs, 1024.0F),
- maxLimit(double(std::numeric_limits<ushort16>::max()) /
+ maxLimit((double(std::numeric_limits<int>::max() - rounding) /
+ double(std::numeric_limits<ushort16>::max())) /
this->f2iScale) {}
void apply(const RawImage& ri) override {
diff --git a/src/external/rawspeed/src/librawspeed/common/ErrorLog.cpp b/src/external/rawspeed/src/librawspeed/common/ErrorLog.cpp
index d188ef83b..801674818 100644
--- a/src/external/rawspeed/src/librawspeed/common/ErrorLog.cpp
+++ b/src/external/rawspeed/src/librawspeed/common/ErrorLog.cpp
@@ -20,7 +20,7 @@
#include "ErrorLog.h"
#include "common/Mutex.h" // for MutexLocker
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/common/Optional.h b/src/external/rawspeed/src/librawspeed/common/Optional.h
new file mode 100644
index 000000000..78a03d538
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/common/Optional.h
@@ -0,0 +1,52 @@
+/*
+ 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
+*/
+
+#pragma once
+
+#include <utility> // for move
+
+namespace rawspeed {
+
+template <class T> class Optional final {
+ T data;
+ bool hasData = false;
+
+public:
+ Optional() = default;
+
+ explicit Optional(T RHS) : data(RHS), hasData(true) {}
+
+ Optional& operator=(T RHS) {
+ Optional tmp(RHS);
+ *this = std::move(tmp);
+ return *this;
+ }
+
+ bool hasValue() const { return hasData; }
+
+ void reset() { hasData = false; }
+
+ T getValue() const {
+ assert(hasValue());
+ return data;
+ }
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/common/RawImage.cpp b/src/external/rawspeed/src/librawspeed/common/RawImage.cpp
index de7a0e81e..7fa9ba26a 100644
--- a/src/external/rawspeed/src/librawspeed/common/RawImage.cpp
+++ b/src/external/rawspeed/src/librawspeed/common/RawImage.cpp
@@ -18,23 +18,26 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "rawspeedconfig.h" // for WITH_SSE2
+#include "rawspeedconfig.h" // for HAVE_PTHREAD
#include "common/RawImage.h"
-#include "AddressSanitizer.h" // for ASan::...
-#include "MemorySanitizer.h" // for MSan::CheckMemIsInitialized
+#include "MemorySanitizer.h" // for MSan
#include "common/Memory.h" // for alignedFree, alignedMalloc...
#include "decoders/RawDecoderException.h" // for ThrowRDE, RawDecoderException
#include "io/IOException.h" // for IOException
#include "parsers/TiffParserException.h" // for TiffParserException
-#include <algorithm> // for min
+#include <algorithm> // for fill_n, min
#include <cassert> // for assert
#include <cmath> // for NAN
-#include <cstdlib> // for free
-#include <cstring> // for memset, memcpy, strdup
+#include <cstdlib> // for size_t
+#include <cstring> // for memcpy, memset
#include <limits> // for numeric_limits
-#include <memory> // for unique_ptr
+#include <memory> // for unique_ptr, make_unique
+#include <utility> // for move, swap
+
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+#include "AddressSanitizer.h" // for ASan::...
+#endif
-using std::fill_n;
using std::string;
namespace rawspeed {
@@ -60,7 +63,7 @@ ImageMetaData::ImageMetaData() {
isoSpeed = 0;
pixelAspectRatio = 1;
fujiRotationPos = 0;
- fill_n(wbCoeffs, 4, NAN);
+ wbCoeffs.fill(NAN);
}
RawImageData::~RawImageData() {
diff --git a/src/external/rawspeed/src/librawspeed/common/RawImage.h b/src/external/rawspeed/src/librawspeed/common/RawImage.h
index 79d8efdc3..d63511afd 100644
--- a/src/external/rawspeed/src/librawspeed/common/RawImage.h
+++ b/src/external/rawspeed/src/librawspeed/common/RawImage.h
@@ -86,7 +86,7 @@ public:
double pixelAspectRatio;
// White balance coefficients of the image
- float wbCoeffs[4];
+ std::array<float, 4> wbCoeffs;
// How many pixels far down the left edge and far up the right edge the image
// corners are when the image is rotated 45 degrees in Fuji rotated sensors.
@@ -206,7 +206,7 @@ protected:
void doLookup(int start_y, int end_y) override;
RawImageDataU16();
- explicit RawImageDataU16(const iPoint2D& dim, uint32 cpp = 1);
+ explicit RawImageDataU16(const iPoint2D& dim_, uint32 cpp_ = 1);
friend class RawImage;
};
@@ -221,7 +221,7 @@ protected:
void fixBadPixel(uint32 x, uint32 y, int component = 0) override;
[[noreturn]] void doLookup(int start_y, int end_y) override;
RawImageDataFloat();
- explicit RawImageDataFloat(const iPoint2D& dim, uint32 cpp = 1);
+ explicit RawImageDataFloat(const iPoint2D& dim_, uint32 cpp_ = 1);
friend class RawImage;
};
diff --git a/src/external/rawspeed/src/librawspeed/common/RawImageDataFloat.cpp b/src/external/rawspeed/src/librawspeed/common/RawImageDataFloat.cpp
index a2f40be6f..06423a20d 100644
--- a/src/external/rawspeed/src/librawspeed/common/RawImageDataFloat.cpp
+++ b/src/external/rawspeed/src/librawspeed/common/RawImageDataFloat.cpp
@@ -18,12 +18,13 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "common/RawImage.h" // for RawImageDataFloat, RawImag...
+#include "common/RawImage.h" // for RawImageDataFloat, TYPE_FL...
#include "common/Common.h" // for uchar8, uint32, writeLog
#include "common/Point.h" // for iPoint2D
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "metadata/BlackArea.h" // for BlackArea
#include <algorithm> // for max, min
+#include <array> // for array
#include <memory> // for operator==, unique_ptr
#include <vector> // for vector
@@ -44,7 +45,8 @@ RawImageDataFloat::RawImageDataFloat() {
void RawImageDataFloat::calculateBlackAreas() {
- float accPixels[4] = {0,0,0,0};
+ std::array<float, 4> accPixels;
+ accPixels.fill(0);
int totalpixels = 0;
for (auto area : blackAreas) {
@@ -258,8 +260,8 @@ RawImageDataFloat::RawImageDataFloat() {
void RawImageDataFloat::scaleValues(int start_y, int end_y) {
int gw = dim.x * cpp;
- float mul[4];
- float sub[4];
+ std::array<float, 4> mul;
+ std::array<float, 4> sub;
for (int i = 0; i < 4; i++) {
int v = i;
if ((mOffset.x&1) != 0)
@@ -289,12 +291,11 @@ RawImageDataFloat::RawImageDataFloat() {
void RawImageDataFloat::fixBadPixel( uint32 x, uint32 y, int component )
{
- float values[4];
- float dist[4];
- float weight[4];
+ std::array<float, 4> values;
+ values.fill(-1);
+ std::array<float, 4> dist = {{}};
+ std::array<float, 4> weight;
- values[0] = values[1] = values[2] = values[3] = -1;
- dist[0] = dist[1] = dist[2] = dist[3] = 0;
uchar8* bad_line = &mBadPixelMap[y*mBadPixelMapPitch];
// Find pixel to the left
diff --git a/src/external/rawspeed/src/librawspeed/common/RawImageDataU16.cpp b/src/external/rawspeed/src/librawspeed/common/RawImageDataU16.cpp
index 7570f6b5d..d47551301 100644
--- a/src/external/rawspeed/src/librawspeed/common/RawImageDataU16.cpp
+++ b/src/external/rawspeed/src/librawspeed/common/RawImageDataU16.cpp
@@ -339,8 +339,8 @@ void RawImageDataU16::scaleValues_plain(int start_y, int end_y) {
// Not SSE2
int gw = dim.x * cpp;
- int mul[4];
- int sub[4];
+ std::array<int, 4> mul;
+ std::array<int, 4> sub;
for (int i = 0; i < 4; i++) {
int v = i;
if ((mOffset.x & 1) != 0)
@@ -488,7 +488,7 @@ void RawImageDataU16::doLookup( int start_y, int end_y )
uint32 delta = lookup >> 16;
v = 15700 *(v & 65535) + (v >> 16);
uint32 pix = base + ((delta * (v & 2047) + 1024) >> 12);
- *pixel = pix;
+ *pixel = clampBits(pix, 16);
pixel++;
}
}
diff --git a/src/external/rawspeed/src/librawspeed/common/RawspeedException.h b/src/external/rawspeed/src/librawspeed/common/RawspeedException.h
index 28a72f86b..53a818853 100644
--- a/src/external/rawspeed/src/librawspeed/common/RawspeedException.h
+++ b/src/external/rawspeed/src/librawspeed/common/RawspeedException.h
@@ -24,6 +24,7 @@
#include "rawspeedconfig.h"
#include "common/Common.h"
+#include <array>
#include <cstdarg>
#include <cstdio>
#include <stdexcept>
@@ -36,7 +37,7 @@ template <typename T>
ThrowException(const char* fmt, ...) {
static constexpr size_t bufSize = 8192;
#if defined(HAVE_CXX_THREAD_LOCAL)
- static thread_local char buf[bufSize];
+ static thread_local std::array<char, bufSize> buf;
#elif defined(HAVE_GCC_THREAD_LOCAL)
static __thread char buf[bufSize];
#else
@@ -47,10 +48,10 @@ ThrowException(const char* fmt, ...) {
va_list val;
va_start(val, fmt);
- vsnprintf(buf, sizeof(buf), fmt, val);
+ vsnprintf(buf.data(), sizeof(buf), fmt, val);
va_end(val);
- writeLog(DEBUG_PRIO_EXTRA, "EXCEPTION: %s", buf);
- throw T(buf);
+ writeLog(DEBUG_PRIO_EXTRA, "EXCEPTION: %s", buf.data());
+ throw T(buf.data());
}
class RawspeedException : public std::runtime_error {
diff --git a/src/external/rawspeed/src/librawspeed/common/SimpleLUT.h b/src/external/rawspeed/src/librawspeed/common/SimpleLUT.h
new file mode 100644
index 000000000..ccc64de50
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/common/SimpleLUT.h
@@ -0,0 +1,67 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2018 Stefan Löffler
+ 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
+*/
+
+#pragma once
+
+#include "common/Common.h" // for clampBits
+#include <algorithm> // for generate_n
+#include <cassert> // for assert
+#include <functional> // for function
+#include <iterator> // for back_inserter
+#include <type_traits> // for enable_if, is_convertible
+#include <vector> // for vector
+
+namespace rawspeed {
+
+template <typename T, int TableBitWidth> class SimpleLUT final {
+public:
+ using value_type = T;
+
+ SimpleLUT() = default;
+
+private:
+ std::vector<value_type> table;
+
+public:
+ template <typename F,
+ typename = std::enable_if<std::is_convertible<
+ F, std::function<value_type(
+ typename decltype(table)::size_type,
+ typename decltype(table)::size_type)>>::value>>
+ explicit SimpleLUT(F&& f) {
+ const auto fullTableSize = 1U << TableBitWidth;
+ table.reserve(fullTableSize);
+ std::generate_n(std::back_inserter(table), fullTableSize,
+ [&f, table = &table]() {
+ // which row [0..fullTableSize) are we filling?
+ const auto i = table->size();
+ return f(i, fullTableSize);
+ });
+ assert(table.size() == fullTableSize);
+ }
+
+ inline value_type operator[](int x) const {
+ unsigned clampedX = clampBits(x, TableBitWidth);
+ return table[clampedX];
+ }
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/common/Spline.h b/src/external/rawspeed/src/librawspeed/common/Spline.h
index fa87f585e..bcfa97e24 100644
--- a/src/external/rawspeed/src/librawspeed/common/Spline.h
+++ b/src/external/rawspeed/src/librawspeed/common/Spline.h
@@ -23,11 +23,12 @@
#include "common/Common.h" // for ushort16
#include "common/Point.h" // for iPoint2D
-#include <algorithm> // for adjacent_find
-#include <algorithm> // for min, max
+#include <algorithm> // for max, min, adjacent_find, for_each
#include <cassert> // for assert
+#include <functional> // for greater_equal
#include <limits> // for numeric_limits
-#include <type_traits> // for enable_if_t, is_arithmetic
+#include <memory> // for allocator_traits<>::value_type
+#include <type_traits> // for is_floating_point, enable_if_t, is_arithm...
#include <vector> // for vector
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/common/TableLookUp.cpp b/src/external/rawspeed/src/librawspeed/common/TableLookUp.cpp
index abaeec3a4..803a323e7 100644
--- a/src/external/rawspeed/src/librawspeed/common/TableLookUp.cpp
+++ b/src/external/rawspeed/src/librawspeed/common/TableLookUp.cpp
@@ -58,8 +58,9 @@ void TableLookUp::setTable(int ntable, const std::vector<ushort16>& table) {
int lower = i > 0 ? table[i - 1] : center;
int upper = i < (nfilled - 1) ? table[i + 1] : center;
int delta = upper - lower;
- t[i * 2] = center - ((upper - lower + 2) / 4);
- t[i * 2 + 1] = delta;
+ t[i * 2] = clampBits(center - ((upper - lower + 2) / 4), 16);
+ t[i * 2 + 1] = ushort16(delta);
+ // FIXME: this is completely broken when the curve is non-monotonic.
}
for (int i = nfilled; i < 65536; i++) {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/AbstractTiffDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/AbstractTiffDecoder.h
index 470c3f2a2..830f2a9bb 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/AbstractTiffDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/AbstractTiffDecoder.h
@@ -22,10 +22,10 @@
#include "decoders/RawDecoder.h" // for RawDecoder
#include "tiff/TiffIFD.h" // for TiffID, TiffRootIFD, TiffRootIFDOwner
-#include "tiff/TiffTag.h" // for TiffTag::IMAGEWIDTH, TiffTag
-#include <algorithm> // for move
+#include "tiff/TiffTag.h" // for IMAGEWIDTH, TiffTag
#include <memory> // for unique_ptr
#include <string> // for string
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.cpp
index 728e260ea..bb53164d4 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.cpp
@@ -24,23 +24,21 @@
#include "common/Point.h" // for iPoint2D
#include "common/RawspeedException.h" // for RawspeedException
#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "decompressors/HuffmanTable.h" // for HuffmanTable
#include "decompressors/SonyArw1Decompressor.h" // for SonyArw1Decompre...
#include "decompressors/SonyArw2Decompressor.h" // for SonyArw2Decompre...
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
-#include "io/BitPumpMSB.h" // for BitPumpMSB
#include "io/Buffer.h" // for Buffer, DataBuffer
#include "io/ByteStream.h" // for ByteStream
#include "io/Endianness.h" // for Endianness, Endi...
-#include "io/IOException.h" // for IOException
#include "metadata/Camera.h" // for Hints
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, CFA_BLUE
#include "tiff/TiffEntry.h" // for TiffEntry
#include "tiff/TiffIFD.h" // for TiffRootIFD, Tif...
-#include "tiff/TiffTag.h" // for TiffTag::DNGPRIV...
+#include "tiff/TiffTag.h" // for DNGPRIVATEDATA
#include <cassert> // for assert
#include <cstring> // for memcpy, size_t
#include <memory> // for unique_ptr
+#include <set> // for set
#include <string> // for operator==, string
#include <vector> // for vector
@@ -198,7 +196,7 @@ RawImage ArwDecoder::decodeRawInternal() {
std::vector<ushort16> curve(0x4001);
TiffEntry *c = raw->getEntry(SONY_CURVE);
- uint32 sony_curve[] = { 0, 0, 0, 0, 0, 4095 };
+ std::array<uint32, 6> sony_curve = {{0, 0, 0, 0, 0, 4095}};
for (uint32 i = 0; i < 4; i++)
sony_curve[i+1] = (c->getU16(i) >> 2) & 0xfff;
@@ -322,8 +320,8 @@ void ArwDecoder::ParseA100WB() {
bs.skipBytes(4);
- ushort16 tmp[4];
bs.setByteOrder(Endianness::little);
+ std::array<ushort16, 4> tmp;
for (auto& coeff : tmp)
coeff = bs.getU16();
@@ -369,11 +367,11 @@ void ArwDecoder::SonyDecrypt(const uint32* ibuf, uint32* obuf, uint32 len,
if (0 == len)
return;
- uint32 pad[128];
+ std::array<uint32, 128> pad;
// Initialize the decryption pad from the key
for (int p=0; p < 4; p++)
- pad[p] = key = key * 48828125UL + 1UL;
+ pad[p] = key = uint32(key * 48828125UL + 1UL);
pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
for (int p=4; p < 127; p++)
pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
@@ -386,7 +384,7 @@ void ArwDecoder::SonyDecrypt(const uint32* ibuf, uint32* obuf, uint32 len,
pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+1+64) & 127];
uint32 pv;
- memcpy(&pv, pad + (p & 127), sizeof(uint32));
+ memcpy(&pv, &(pad[p & 127]), sizeof(uint32));
uint32 bv;
memcpy(&bv, ibuf, sizeof(uint32));
@@ -420,22 +418,29 @@ void ArwDecoder::GetWB() {
uint32 off = sony_offset->getU32();
assert(sony_length != nullptr);
- uint32 len = sony_length->getU32();
+ // The Decryption is done in blocks of 4 bytes.
+ uint32 len = roundDown(sony_length->getU32(), 4);
assert(sony_key != nullptr);
uint32 key = getU32LE(sony_key->getData(4));
// "Decrypt" IFD
const auto& ifd_crypt = priv->getRootIfdData();
- auto ifd_size = ifd_crypt.getSize();
- auto ifd_decoded = Buffer::Create(ifd_size);
+ const auto EncryptedBuffer = ifd_crypt.getSubView(off, len);
+ // We do have to prepend 'off' padding, because TIFF uses absolute offsets.
+ const auto DecryptedBufferSize = off + EncryptedBuffer.getSize();
+ auto DecryptedBuffer = Buffer::Create(DecryptedBufferSize);
- SonyDecrypt(reinterpret_cast<const uint32*>(ifd_crypt.getData(off, len)),
- reinterpret_cast<uint32*>(ifd_decoded.get() + off), len / 4,
+ SonyDecrypt(reinterpret_cast<const uint32*>(EncryptedBuffer.begin()),
+ reinterpret_cast<uint32*>(DecryptedBuffer.get() + off), len / 4,
key);
NORangesSet<Buffer> ifds_decoded;
- Buffer decIFD(move(ifd_decoded), ifd_size);
+ Buffer decIFD(std::move(DecryptedBuffer), DecryptedBufferSize);
+ const Buffer Padding(decIFD.getSubView(0, off));
+ // The Decrypted Root Ifd can not point to preceding padding buffer.
+ ifds_decoded.emplace(Padding);
+
DataBuffer dbIDD(decIFD, priv->getRootIfdData().getByteOrder());
TiffRootIFD encryptedIFD(nullptr, &ifds_decoded, dbIDD, off);
diff --git a/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.h
index ddebea2d3..c89a21ba5 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/ArwDecoder.h
@@ -26,7 +26,7 @@
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "io/ByteStream.h" // for ByteStream
#include "tiff/TiffIFD.h" // for TiffIFD (ptr only), TiffRo...
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.cpp
index ff5812c93..004e1a568 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.cpp
@@ -21,25 +21,25 @@
*/
#include "decoders/Cr2Decoder.h"
-#include "common/Common.h" // for ushort16, clampBits, uint32
-#include "common/Point.h" // for iPoint2D
-#include "common/RawspeedException.h" // for RawspeedException
-#include "decoders/RawDecoderException.h" // for RawDecoderException, Thro...
-#include "decompressors/Cr2Decompressor.h" // for Cr2Decompressor
+#include "common/Common.h" // for uint32, ushort16
+#include "common/Point.h" // for iPoint2D
+#include "common/RawspeedException.h" // for RawspeedException
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/Cr2Decompressor.h" // for Cr2Decompressor, Cr2S...
#include "interpolators/Cr2sRawInterpolator.h" // for Cr2sRawInterpolator
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for getHostEndianness, Endian...
-#include "io/IOException.h" // for IOException
-#include "metadata/Camera.h" // for Hints
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN, CFAC...
-#include "parsers/TiffParserException.h" // for ThrowTPE
-#include "tiff/TiffEntry.h" // for TiffEntry, TiffDataType::...
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag::CANONCO...
-#include <array> // for array
-#include <cassert> // for assert
-#include <memory> // for unique_ptr, allocator
-#include <string> // for string, operator==
+#include "io/Endianness.h" // for Endianness, Endiannes...
+#include "metadata/Camera.h" // for Hints
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, CFA_BLUE
+#include "parsers/TiffParserException.h" // for ThrowTPE
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_SHORT
+#include "tiff/TiffTag.h" // for TiffTag, CANONCOLORDATA
+#include <array> // for array
+#include <cassert> // for assert
+#include <memory> // for unique_ptr, allocator...
+#include <string> // for operator==, string
+#include <vector> // for vector
// IWYU pragma: no_include <ext/alloc_traits.h>
using std::string;
@@ -54,7 +54,8 @@ bool Cr2Decoder::isAppropriateDecoder(const TiffRootIFD* rootIFD,
// FIXME: magic
- return make == "Canon" || (make == "Kodak" && model == "DCS560C");
+ return make == "Canon" ||
+ (make == "Kodak" && (model == "DCS520C" || model == "DCS560C"));
}
RawImage Cr2Decoder::decodeOldFormat() {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.h b/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.h
index 9def2ff80..d5a80fed1 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/Cr2Decoder.h
@@ -23,7 +23,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/CrwDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/CrwDecoder.cpp
index 264bd26b2..033273770 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/CrwDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/CrwDecoder.cpp
@@ -21,24 +21,25 @@
*/
#include "decoders/CrwDecoder.h"
-#include "common/Common.h" // for ushort16, uint32
+#include "common/Common.h" // for ushort16, uchar8, uint32
#include "common/Point.h" // for iPoint2D
#include "common/RawspeedException.h" // for RawspeedException
-#include "decoders/RawDecoderException.h" // for RawDecoderException (ptr ...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/CrwDecompressor.h" // for CrwDecompressor
+#include "io/Buffer.h" // for Buffer
#include "metadata/Camera.h" // for Hints
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN, CFAC...
-#include "tiff/CiffEntry.h" // for CiffEntry, CiffDataType::...
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, CFA_BLUE, CFA_RED
+#include "tiff/CiffEntry.h" // for CiffEntry, CIFF_SHORT
#include "tiff/CiffIFD.h" // for CiffIFD
-#include "tiff/CiffTag.h" // for CiffTag, CiffTag::CIFF_MA...
-#include <algorithm> // for move
+#include "tiff/CiffTag.h" // for CIFF_MAKEMODEL, CIFF_SHOT...
#include <array> // for array
#include <cassert> // for assert
-#include <cmath> // for copysignf, expf, logf
+#include <cmath> // for abs, copysignf, expf, logf
+#include <cstring> // for memcmp, size_t
#include <memory> // for unique_ptr
#include <string> // for string
+#include <utility> // for move
#include <vector> // for vector
-// IWYU pragma: no_include <bits/std_abs.h>
using std::vector;
using std::string;
@@ -49,12 +50,11 @@ namespace rawspeed {
class CameraMetaData;
bool CrwDecoder::isCRW(const Buffer* input) {
- static const char magic[] = "HEAPCCDR";
+ static const std::array<char, 8> magic = {
+ {'H', 'E', 'A', 'P', 'C', 'C', 'D', 'R'}};
static const size_t magic_offset = 6;
- static const size_t magic_size = sizeof(magic) - 1; // excluding \0
- static_assert(magic_size == 8, "Wrong magic size!");
- const unsigned char* data = input->getData(magic_offset, magic_size);
- return 0 == memcmp(&data[0], magic, magic_size);
+ const unsigned char* data = input->getData(magic_offset, magic.size());
+ return 0 == memcmp(data, magic.data(), magic.size());
}
CrwDecoder::CrwDecoder(std::unique_ptr<const CiffIFD> rootIFD,
@@ -168,7 +168,7 @@ void CrwDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
// correct offset for most cameras
int offset = hints.get("wb_offset", 120);
- ushort16 key[] = { 0x410, 0x45f3 };
+ std::array<ushort16, 2> key = {{0x410, 0x45f3}};
if (! hints.has("wb_mangle"))
key[0] = key[1] = 0;
diff --git a/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.cpp
index cdad0691e..69cfe4e72 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.cpp
@@ -20,14 +20,15 @@
*/
#include "decoders/DcrDecoder.h"
-#include "common/NORangesSet.h" // for NORangesSet
-#include "decoders/RawDecoderException.h" // for RawDecoderException (ptr ...
+#include "common/NORangesSet.h" // for set
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/KodakDecompressor.h" // for KodakDecompressor
#include "io/ByteStream.h" // for ByteStream
-#include "tiff/TiffEntry.h" // for TiffEntry, TiffDataType::...
-#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag::COMPRES...
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_SHORT
+#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffID
+#include "tiff/TiffTag.h" // for COMPRESSION, KODAK_IFD
#include <cassert> // for assert
+#include <memory> // for unique_ptr
#include <string> // for operator==, string
namespace rawspeed {
@@ -69,12 +70,13 @@ RawImage DcrDecoder::decodeRawInternal() {
ifdoffset->getU32());
TiffEntry* linearization = kodakifd.getEntryRecursive(KODAK_LINEARIZATION);
- if (!linearization || linearization->count != 1024 ||
+ if (!linearization ||
+ !(linearization->count == 1024 || linearization->count == 4096) ||
linearization->type != TIFF_SHORT)
ThrowRDE("Couldn't find the linearization table");
assert(linearization != nullptr);
- auto linTable = linearization->getU16Array(1024);
+ auto linTable = linearization->getU16Array(linearization->count);
RawImageCurveGuard curveHandler(&mRaw, linTable, uncorrectedRawValues);
@@ -92,7 +94,17 @@ RawImage DcrDecoder::decodeRawInternal() {
}
}
- KodakDecompressor k(mRaw, input, uncorrectedRawValues);
+ const int bps = [CurveSize = linearization->count]() -> int {
+ switch (CurveSize) {
+ case 1024:
+ return 10;
+ case 4096:
+ return 12;
+ }
+ __builtin_unreachable();
+ }();
+
+ KodakDecompressor k(mRaw, input, bps, uncorrectedRawValues);
k.decompress();
return mRaw;
diff --git a/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.h
index 44ed4c833..82cf94260 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/DcrDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/SimpleTiffDecoder.h" // for SimpleTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/DcsDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/DcsDecoder.h
index 252aff385..c6ab0fa6c 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/DcsDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/DcsDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/SimpleTiffDecoder.h" // for SimpleTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/DngDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/DngDecoder.cpp
index 80729b2cb..70a459f47 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/DngDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/DngDecoder.cpp
@@ -20,28 +20,32 @@
#include "rawspeedconfig.h" // for HAVE_JPEG, HAVE_ZLIB
#include "decoders/DngDecoder.h"
-#include "common/Common.h" // for uint32, writeLog
+#include "common/Common.h" // for uint32, roundUpDi...
#include "common/DngOpcodes.h" // for DngOpcodes
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/NORangesSet.h" // for set
#include "common/Point.h" // for iPoint2D, iRectan...
#include "common/RawspeedException.h" // for RawspeedException
#include "decoders/RawDecoderException.h" // for ThrowRDE, RawDeco...
-#include "decompressors/AbstractDngDecompressor.h" // for AbstractDngDecomp...
-#include "io/Buffer.h" // for Buffer
+#include "decompressors/AbstractDngDecompressor.h" // for DngSliceElement
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "metadata/BlackArea.h" // for BlackArea
#include "metadata/Camera.h" // for Camera
#include "metadata/CameraMetaData.h" // for CameraMetaData
#include "metadata/ColorFilterArray.h" // for CFAColor, ColorFi...
-#include "tiff/TiffEntry.h" // for TiffEntry, TiffDa...
+#include "parsers/TiffParserException.h" // for ThrowTPE
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_LONG
#include "tiff/TiffIFD.h" // for TiffIFD, TiffRootIFD
-#include "tiff/TiffTag.h" // for TiffTag::ACTIVEAREA
-#include <algorithm> // for move
+#include "tiff/TiffTag.h" // for ACTIVEAREA, TILEO...
+#include <algorithm> // for any_of
+#include <array> // for array, array<>::v...
#include <cassert> // for assert
-#include <cstring> // for memset
#include <limits> // for numeric_limits
#include <map> // for map
#include <memory> // for unique_ptr
#include <stdexcept> // for out_of_range
#include <string> // for string, operator+
+#include <utility> // for move, pair
#include <vector> // for vector, allocator
using std::vector;
@@ -105,6 +109,7 @@ void DngDecoder::dropUnsuportedChunks(std::vector<const TiffIFD*>* data) {
#ifdef HAVE_ZLIB
case 8: // deflate
#endif
+ case 9: // VC-5 as used by GoPro
#ifdef HAVE_JPEG
case 0x884c: // lossy JPEG
#endif
@@ -272,10 +277,17 @@ void DngDecoder::decodeData(const TiffIFD* raw, uint32 sample_format) {
"JPEG-compressed data.");
}
- uint32 predictor = -1;
+ uint32 predictor = ~0U;
if (raw->hasEntry(PREDICTOR))
predictor = raw->getEntry(PREDICTOR)->getU32();
+ // Some decompressors (such as VC5) may depend on the white point
+ if (raw->hasEntry(WHITELEVEL)) {
+ TiffEntry* whitelevel = raw->getEntry(WHITELEVEL);
+ if (whitelevel->isInt())
+ mRaw->whitePoint = whitelevel->getU32();
+ }
+
AbstractDngDecompressor slices(mRaw, getTilingDescription(raw), compression,
mFixLjpeg, bps, predictor);
@@ -479,8 +491,12 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
// Apply stage 1 opcodes
if (applyStage1DngOpcodes && raw->hasEntry(OPCODELIST1)) {
try {
- DngOpcodes codes(mRaw, raw->getEntry(OPCODELIST1));
- codes.applyOpCodes(mRaw);
+ TiffEntry* opcodes = raw->getEntry(OPCODELIST1);
+ // The entry might exist, but it might be empty, which means no opcodes
+ if (opcodes->count > 0) {
+ DngOpcodes codes(mRaw, opcodes);
+ codes.applyOpCodes(mRaw);
+ }
} catch (RawDecoderException& e) {
// We push back errors from the opcode parser, since the image may still
// be usable
@@ -498,8 +514,13 @@ void DngDecoder::handleMetadata(const TiffIFD* raw) {
mRaw->sixteenBitLookup();
}
- // Default white level is (2 ** BitsPerSample) - 1
- mRaw->whitePoint = (1UL << bps) - 1UL;
+ if (mRaw->getDataType() == TYPE_USHORT16) {
+ // Default white level is (2 ** BitsPerSample) - 1
+ mRaw->whitePoint = (1UL << bps) - 1UL;
+ } else if (mRaw->getDataType() == TYPE_FLOAT32) {
+ // Default white level is 1.0f. But we can't represent that here.
+ mRaw->whitePoint = 65535;
+ }
if (raw->hasEntry(WHITELEVEL)) {
TiffEntry *whitelevel = raw->getEntry(WHITELEVEL);
@@ -587,7 +608,7 @@ void DngDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
mRaw->metadata.wbCoeffs[2] =
1 - mRaw->metadata.wbCoeffs[0] - mRaw->metadata.wbCoeffs[1];
- const float d65_white[3] = {0.950456, 1, 1.088754};
+ const std::array<float, 3> d65_white = {{0.950456, 1, 1.088754}};
for (uint32 i = 0; i < 3; i++)
mRaw->metadata.wbCoeffs[i] /= d65_white[i];
}
@@ -709,7 +730,7 @@ bool DngDecoder::decodeBlackLevels(const TiffIFD* raw) {
TiffEntry *blackleveldeltav = raw->getEntry(BLACKLEVELDELTAV);
if (static_cast<int>(blackleveldeltav->count) < mRaw->dim.y)
ThrowRDE("BLACKLEVELDELTAV array is too small");
- float black_sum[2] = {0.0F, 0.0F};
+ std::array<float, 2> black_sum = {{}};
for (int i = 0; i < mRaw->dim.y; i++)
black_sum[i&1] += blackleveldeltav->getFloat(i);
@@ -730,7 +751,7 @@ bool DngDecoder::decodeBlackLevels(const TiffIFD* raw) {
TiffEntry *blackleveldeltah = raw->getEntry(BLACKLEVELDELTAH);
if (static_cast<int>(blackleveldeltah->count) < mRaw->dim.x)
ThrowRDE("BLACKLEVELDELTAH array is too small");
- float black_sum[2] = {0.0F, 0.0F};
+ std::array<float, 2> black_sum = {{}};
for (int i = 0; i < mRaw->dim.x; i++)
black_sum[i&1] += blackleveldeltah->getFloat(i);
diff --git a/src/external/rawspeed/src/librawspeed/decoders/ErfDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/ErfDecoder.h
index b884b4099..c286cdbb1 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/ErfDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/ErfDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/SimpleTiffDecoder.h" // for SimpleTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.cpp
index 027df1a3a..41ae2d716 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.cpp
@@ -21,22 +21,25 @@
*/
#include "decoders/IiqDecoder.h"
-#include "common/Common.h" // for uint32, int32, ushort16
-#include "common/Point.h" // for iPoint2D
-#include "common/Spline.h" // for calculateCurve
-#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "io/BitPumpMSB32.h" // for BitPumpMSB32
-#include "io/Buffer.h" // for Buffer, DataBuffer
-#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for Endianness, Endianness::li...
-#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffID
-#include <algorithm> // for move, sort, adjacent_find
-#include <cassert> // for assert
-#include <functional> // for greater_equal
-#include <iterator> // for advance, begin, end, next
-#include <memory> // for unique_ptr
-#include <string> // for operator==, string
-#include <vector> // for vector
+#include "common/Common.h" // for uint32, ushort16
+#include "common/Point.h" // for iPoint2D
+#include "common/Spline.h" // for Spline, Spline<>::va...
+#include "decoders/RawDecoder.h" // for RawDecoder::(anonymous)
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/PhaseOneDecompressor.h" // for PhaseOneStrip, Phase...
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endianne...
+#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffID
+#include <algorithm> // for adjacent_find, gener...
+#include <array> // for array, array<>::cons...
+#include <cassert> // for assert
+#include <functional> // for greater_equal
+#include <iterator> // for advance, next, begin
+#include <memory> // for unique_ptr
+#include <string> // for operator==, string
+#include <utility> // for move
+#include <vector> // for vector
namespace rawspeed {
@@ -61,7 +64,7 @@ bool IiqDecoder::isAppropriateDecoder(const TiffRootIFD* rootIFD,
}
// FIXME: this is very close to SamsungV0Decompressor::computeStripes()
-std::vector<IiqDecoder::IiqStrip>
+std::vector<PhaseOneStrip>
IiqDecoder::computeSripes(const Buffer& raw_data,
std::vector<IiqOffset>&& offsets,
uint32 height) const {
@@ -82,7 +85,7 @@ IiqDecoder::computeSripes(const Buffer& raw_data,
return a.offset < b.offset;
});
- std::vector<IiqDecoder::IiqStrip> slices;
+ std::vector<PhaseOneStrip> slices;
slices.reserve(height);
auto offset_iterator = std::begin(offsets);
@@ -198,13 +201,15 @@ RawImage IiqDecoder::decodeRawInternal() {
// which will be used much like end()
offsets.emplace_back(height, raw_data.getSize());
- const std::vector<IiqStrip> strips(
+ std::vector<PhaseOneStrip> strips(
computeSripes(raw_data, std::move(offsets), height));
mRaw->dim = iPoint2D(width, height);
+
+ PhaseOneDecompressor p(mRaw, std::move(strips));
mRaw->createData();
+ p.decompress();
- DecodePhaseOneC(strips, width, height);
if (correction_meta_data.getSize() != 0 && iiq)
CorrectPhaseOneC(correction_meta_data, split_row, split_col);
@@ -214,54 +219,6 @@ RawImage IiqDecoder::decodeRawInternal() {
return mRaw;
}
-void IiqDecoder::DecodeStrip(const IiqStrip& strip, uint32 width,
- uint32 height) {
- const int length[] = {8, 7, 6, 9, 11, 10, 5, 12, 14, 13};
-
- BitPumpMSB32 pump(strip.bs);
-
- int32 pred[2];
- uint32 len[2];
- pred[0] = pred[1] = 0;
- auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, strip.n));
- for (uint32 col = 0; col < width; col++) {
- if (col >= (width & -8))
- len[0] = len[1] = 14;
- else if ((col & 7) == 0) {
- for (unsigned int& i : len) {
- int j = 0;
-
- for (; j < 5; j++) {
- if (pump.getBits(1) != 0) {
- if (col == 0)
- ThrowRDE("Can not initialize lengths. Data is corrupt.");
-
- // else, we have previously initialized lengths, so we are fine
- break;
- }
- }
-
- assert((col == 0 && j > 0) || col != 0);
- if (j > 0)
- i = length[2 * (j - 1) + pump.getBits(1)];
- }
- }
-
- int i = len[col & 1];
- if (i == 14)
- img[col] = pred[col & 1] = pump.getBits(16);
- else
- img[col] = pred[col & 1] +=
- static_cast<signed>(pump.getBits(i)) + 1 - (1 << (i - 1));
- }
-}
-
-void IiqDecoder::DecodePhaseOneC(const std::vector<IiqStrip>& strips,
- uint32 width, uint32 height) {
- for (const auto& strip : strips)
- DecodeStrip(strip, width, height);
-}
-
void IiqDecoder::CorrectPhaseOneC(ByteStream meta_data, uint32 split_row,
uint32 split_col) {
meta_data.skipBytes(8);
diff --git a/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.h
index d414b2dbe..041d170ae 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/IiqDecoder.h
@@ -24,15 +24,16 @@
#include "common/Common.h" // for uint32
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
-#include "io/ByteStream.h" // for ByteStream
#include "tiff/TiffIFD.h" // for TiffRootIFD (ptr only)
-#include <algorithm> // for move
+#include <utility> // for move
#include <vector> // for vector
namespace rawspeed {
-class CameraMetaData;
class Buffer;
+class ByteStream;
+class CameraMetaData;
+struct PhaseOneStrip;
class IiqDecoder final : public AbstractTiffDecoder {
struct IiqOffset {
@@ -43,18 +44,9 @@ class IiqDecoder final : public AbstractTiffDecoder {
IiqOffset(uint32 block, uint32 offset_) : n(block), offset(offset_) {}
};
- struct IiqStrip {
- const int n;
- const ByteStream bs;
-
- IiqStrip(int block, ByteStream bs_) : n(block), bs(std::move(bs_)) {}
- };
-
- std::vector<IiqStrip> computeSripes(const Buffer& raw_data,
- std::vector<IiqOffset>&& offsets,
- uint32 height) const;
-
- void DecodeStrip(const IiqStrip& strip, uint32 width, uint32 height);
+ std::vector<PhaseOneStrip> computeSripes(const Buffer& raw_data,
+ std::vector<IiqOffset>&& offsets,
+ uint32 height) const;
public:
static bool isAppropriateDecoder(const Buffer* file);
@@ -71,8 +63,6 @@ public:
protected:
int getDecoderVersion() const override { return 0; }
uint32 black_level = 0;
- void DecodePhaseOneC(const std::vector<IiqStrip>& strips, uint32 width,
- uint32 height);
void CorrectPhaseOneC(ByteStream meta_data, uint32 split_row,
uint32 split_col);
void CorrectQuadrantMultipliersCombined(ByteStream data, uint32 split_row,
diff --git a/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.cpp
index 53f962e7a..23e95f006 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.cpp
@@ -56,13 +56,23 @@ RawImage KdcDecoder::decodeRawInternal() {
if (7 != compression)
ThrowRDE("Unsupported compression %d", compression);
+ TiffEntry* ifdoffset = mRootIFD->getEntryRecursive(KODAK_IFD2);
+ if (!ifdoffset)
+ ThrowRDE("Couldn't find the Kodak IFD offset");
+
+ NORangesSet<Buffer> ifds;
+
+ assert(ifdoffset != nullptr);
+ TiffRootIFD kodakifd(nullptr, &ifds, ifdoffset->getRootIfdData(),
+ ifdoffset->getU32());
+
uint32 width = 0;
uint32 height = 0;
- TiffEntry *ew = mRootIFD->getEntryRecursive(KODAK_KDC_WIDTH);
- TiffEntry *eh = mRootIFD->getEntryRecursive(KODAK_KDC_HEIGHT);
+ TiffEntry* ew = kodakifd.getEntryRecursive(KODAK_KDC_SENSOR_WIDTH);
+ TiffEntry* eh = kodakifd.getEntryRecursive(KODAK_KDC_SENSOR_HEIGHT);
if (ew && eh) {
- width = ew->getU32()+80;
- height = eh->getU32()+70;
+ width = ew->getU32();
+ height = eh->getU32();
} else
ThrowRDE("Unable to retrieve image size");
diff --git a/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.h
index ebd20372d..5e5038ec1 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/KdcDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/MefDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/MefDecoder.h
index eb336f1b7..66cb2808a 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/MefDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/MefDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/SimpleTiffDecoder.h" // for SimpleTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/MosDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/MosDecoder.cpp
index 3c2e0bbfd..2e0c62125 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/MosDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/MosDecoder.cpp
@@ -33,12 +33,12 @@
#include "tiff/TiffEntry.h" // for TiffEntry
#include "tiff/TiffIFD.h" // for TiffRootIFD, Tif...
#include "tiff/TiffTag.h" // for TiffTag::TILEOFF...
-#include <algorithm> // for move
#include <cassert> // for assert
#include <cstring> // for memchr
#include <istream> // for istringstream
#include <memory> // for unique_ptr
#include <string> // for string, allocator
+#include <utility> // for move
using std::string;
@@ -162,7 +162,7 @@ void MosDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
// check for nulltermination of string inside bounds
if (!memchr(bs.peekData(bs.getRemainSize()), 0, bs.getRemainSize()))
break;
- uint32 tmp[4] = {0};
+ std::array<uint32, 4> tmp = {{}};
std::istringstream iss(bs.peekString());
iss >> tmp[0] >> tmp[1] >> tmp[2] >> tmp[3];
if (!iss.fail() && tmp[0] > 0 && tmp[1] > 0 && tmp[2] > 0 &&
diff --git a/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.cpp
index 6e91d8062..0c8dadec4 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.cpp
@@ -23,15 +23,14 @@
#include "decoders/MrwDecoder.h"
#include "common/Common.h" // for uint32
#include "common/Point.h" // for iPoint2D
-#include "decoders/RawDecoderException.h" // for RawDecoderExcept...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
-#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/Buffer.h" // for DataBuffer, Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for Endianness::big
-#include "io/IOException.h" // for IOException
+#include "io/Endianness.h" // for Endianness, Endi...
#include "metadata/Camera.h" // for Hints
#include "parsers/TiffParser.h" // for TiffParser
-#include "tiff/TiffIFD.h" // for TiffID, TiffRoot...
+#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
#include <cassert> // for assert
#include <cstring> // for memcmp, size_t
#include <memory> // for unique_ptr
@@ -43,12 +42,9 @@ class CameraMetaData;
MrwDecoder::MrwDecoder(const Buffer* file) : RawDecoder(file) { parseHeader(); }
int MrwDecoder::isMRW(const Buffer* input) {
- static const char magic[] = {0x00, 'M', 'R', 'M'};
- static const size_t magic_size = sizeof(magic);
- static_assert(4 == magic_size, "wrong magic size");
-
- const unsigned char* data = input->getData(0, magic_size);
- return 0 == memcmp(&data[0], magic, magic_size);
+ static const std::array<char, 4> magic = {{0x00, 'M', 'R', 'M'}};
+ const unsigned char* data = input->getData(0, magic.size());
+ return 0 == memcmp(data, magic.data(), magic.size());
}
void MrwDecoder::parseHeader() {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.h
index 59611896a..2c50fddb4 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/MrwDecoder.h
@@ -40,7 +40,7 @@ class MrwDecoder final : public RawDecoder {
Buffer imageData;
uint32 bpp = 0;
uint32 packed = 0;
- float wb_coeffs[4] = {NAN, NAN, NAN, NAN};
+ std::array<float, 4> wb_coeffs = {{NAN, NAN, NAN, NAN}};
public:
explicit MrwDecoder(const Buffer* file);
diff --git a/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.cpp
index 72fa3b85b..63e410cd2 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.cpp
@@ -22,23 +22,23 @@
#include "decoders/NefDecoder.h"
#include "common/Common.h" // for uint32, uchar8
#include "common/Point.h" // for iPoint2D
-#include "decoders/RawDecoderException.h" // for ThrowRDE, RawDec...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/NikonDecompressor.h" // for NikonDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/BitPumpMSB.h" // for BitPumpMSB
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for getU16BE, getU32LE
-#include "io/IOException.h" // for IOException, Thr...
+#include "io/Endianness.h" // for getU16BE, Endian...
+#include "io/IOException.h" // for ThrowIOE
#include "metadata/Camera.h" // for Hints
#include "metadata/CameraMetaData.h" // for CameraMetaData
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN
-#include "tiff/TiffEntry.h" // for TiffEntry, TiffD...
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, CFA_BLUE
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_...
#include "tiff/TiffIFD.h" // for TiffRootIFD, Tif...
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag...
+#include "tiff/TiffTag.h" // for TiffTag, IMAGELE...
+#include <algorithm> // for min
#include <cassert> // for assert
#include <cmath> // for pow, exp, log
-#include <cstring> // for strncmp
#include <memory> // for unique_ptr, allo...
#include <sstream> // for operator<<, ostr...
#include <string> // for string, operator==
@@ -120,9 +120,9 @@ RawImage NefDecoder::decodeRawInternal() {
ByteStream rawData(mFile, offsets->getU32(), counts->getU32());
- NikonDecompressor n(mRaw, bitPerPixel);
+ NikonDecompressor n(mRaw, meta->getData(), bitPerPixel);
mRaw->createData();
- n.decompress(meta->getData(), rawData, uncorrectedRawValues);
+ n.decompress(rawData, uncorrectedRawValues);
return mRaw;
}
@@ -509,9 +509,9 @@ void NefDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
ByteStream bs = wb->getData();
bs.skipBytes(version == 0x204 ? 284 : 4);
- uchar8 buf[14+8];
+ std::array<uchar8, 14 + 8> buf;
for (unsigned char& i : buf) {
- cj += ci * ck;
+ cj = uchar8(cj + ci * ck); // modulo arithmetics.
i = bs.getByte() ^ cj;
ck++;
}
@@ -519,11 +519,11 @@ void NefDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
// Finally set the WB coeffs
uint32 off = (version == 0x204) ? 6 : 14;
mRaw->metadata.wbCoeffs[0] =
- static_cast<float>(getU16BE(buf + off + 0));
+ static_cast<float>(getU16BE(buf.data() + off + 0));
mRaw->metadata.wbCoeffs[1] =
- static_cast<float>(getU16BE(buf + off + 2));
+ static_cast<float>(getU16BE(buf.data() + off + 2));
mRaw->metadata.wbCoeffs[2] =
- static_cast<float>(getU16BE(buf + off + 6));
+ static_cast<float>(getU16BE(buf.data() + off + 6));
}
}
} else if (mRootIFD->hasEntryRecursive(static_cast<TiffTag>(0x0014))) {
@@ -697,7 +697,9 @@ std::vector<ushort16> NefDecoder::gammaCurve(double pwr, double ts, int mode,
std::vector<ushort16> curve(65536);
int i;
- double g[6], bnd[2]={0,0}, r;
+ std::array<double, 6> g;
+ std::array<double, 2> bnd = {{}};
+ double r;
g[0] = pwr;
g[1] = ts;
g[2] = g[3] = g[4] = 0;
diff --git a/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.h
index 1d14aa830..6acc73e14 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/NefDecoder.h
@@ -25,9 +25,9 @@
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "decoders/RawDecoder.h" // for RawDecoder::RawSlice
#include "tiff/TiffIFD.h" // for TiffIFD (ptr only), TiffRo...
-#include <algorithm> // for move
#include <array> // for array
#include <string> // for string
+#include <utility> // for move
#include <vector> // for vector
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.cpp
index 0063dd128..4a92fe8da 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.cpp
@@ -21,26 +21,20 @@
*/
#include "decoders/OrfDecoder.h"
-#include "common/Common.h" // for uint32, ushort16
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/Common.h" // for uint32, uchar8
+#include "common/NORangesSet.h" // for set
#include "common/Point.h" // for iPoint2D
-#include "decoders/RawDecoderException.h" // for RawDecoderExcept...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/OlympusDecompressor.h" // for OlympusDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
-#include "io/BitPumpMSB.h" // for BitPumpMSB
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for Endianness
-#include "io/IOException.h" // for IOException
-#include "metadata/Camera.h" // for Hints
+#include "io/Endianness.h" // for Endianness, getH...
#include "metadata/ColorFilterArray.h" // for ColorFilterArray
-#include "tiff/TiffEntry.h" // for TiffEntry
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_...
#include "tiff/TiffIFD.h" // for TiffRootIFD, Tif...
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag...
-#include <algorithm> // for min
-#include <cassert> // for assert
-#include <cmath> // for signbit
-#include <cstdlib> // for abs
+#include "tiff/TiffTag.h" // for STRIPOFFSETS
+#include <array> // for array
#include <memory> // for unique_ptr
#include <string> // for operator==, string
@@ -122,48 +116,108 @@ RawImage OrfDecoder::decodeRawInternal() {
ByteStream input(handleSlices());
- if (raw->getEntry(STRIPOFFSETS)->count != 1 ||
- hints.has("force_uncompressed")) {
- mRaw->createData();
- decodeUncompressed(input, width, height, input.getSize());
- } else {
- OlympusDecompressor o(mRaw);
- mRaw->createData();
- o.decompress(std::move(input));
- }
+ if (decodeUncompressed(input, width, height, input.getSize()))
+ return mRaw;
+
+ if (raw->getEntry(STRIPOFFSETS)->count != 1)
+ ThrowRDE("%u stripes, and not uncompressed. Unsupported.",
+ raw->getEntry(STRIPOFFSETS)->count);
+
+ OlympusDecompressor o(mRaw);
+ mRaw->createData();
+ o.decompress(std::move(input));
return mRaw;
}
-void OrfDecoder::decodeUncompressed(const ByteStream& s, uint32 w, uint32 h,
+bool OrfDecoder::decodeUncompressed(const ByteStream& s, uint32 w, uint32 h,
uint32 size) {
UncompressedDecompressor u(s, mRaw);
- if (hints.has("packed_with_control"))
+ // FIXME: most of this logic should be in UncompressedDecompressor,
+ // one way or another.
+
+ if (size == h * ((w * 12 / 8) + ((w + 2) / 10))) {
+ // 12-bit packed 'with control' raw
+ mRaw->createData();
u.decode12BitRaw<Endianness::little, false, true>(w, h);
- else if (hints.has("jpeg32_bitorder")) {
+ return true;
+ }
+
+ if (size == w * h * 12 / 8) { // We're in a 12-bit packed raw
iPoint2D dimensions(w, h);
iPoint2D pos(0, 0);
+ mRaw->createData();
u.readUncompressedRaw(dimensions, pos, w * 12 / 8, 12, BitOrder_MSB32);
- } else if (size >= w * h * 2) { // We're in an unpacked raw
+ return true;
+ }
+
+ if (size == w * h * 2) { // We're in an unpacked raw
+ mRaw->createData();
// FIXME: seems fishy
if (s.getByteOrder() == getHostEndianness())
u.decodeRawUnpacked<12, Endianness::little>(w, h);
else
u.decode12BitRawUnpackedLeftAligned<Endianness::big>(w, h);
- } else if (size >= w*h*3/2) { // We're in one of those weird interlaced packed raws
+ return true;
+ }
+
+ if (size >
+ w * h * 3 / 2) { // We're in one of those weird interlaced packed raws
+ mRaw->createData();
u.decode12BitRaw<Endianness::big, true>(w, h);
- } else {
- ThrowRDE("Don't know how to handle the encoding in this file");
+ return true;
+ }
+
+ // Does not appear to be uncomporessed. Maybe it's compressed?
+ return false;
+}
+
+void OrfDecoder::parseCFA() {
+ if (!mRootIFD->hasEntryRecursive(EXIFCFAPATTERN))
+ ThrowRDE("No EXIFCFAPATTERN entry found!");
+
+ TiffEntry* CFA = mRootIFD->getEntryRecursive(EXIFCFAPATTERN);
+ if (CFA->type != TiffDataType::TIFF_UNDEFINED || CFA->count != 8) {
+ ThrowRDE("Bad EXIFCFAPATTERN entry (type %u, count %u).", CFA->type,
+ CFA->count);
+ }
+
+ iPoint2D cfaSize(CFA->getU16(0), CFA->getU16(1));
+ if (cfaSize != iPoint2D{2, 2})
+ ThrowRDE("Bad CFA size: (%i, %i)", cfaSize.x, cfaSize.y);
+
+ mRaw->cfa.setSize(cfaSize);
+
+ auto int2enum = [](uchar8 i) -> CFAColor {
+ switch (i) {
+ case 0:
+ return CFA_RED;
+ case 1:
+ return CFA_GREEN;
+ case 2:
+ return CFA_BLUE;
+ default:
+ ThrowRDE("Unexpected CFA color: %u", i);
+ }
+ };
+
+ for (int y = 0; y < cfaSize.y; y++) {
+ for (int x = 0; x < cfaSize.x; x++) {
+ uchar8 c1 = CFA->getByte(4 + x + y * cfaSize.x);
+ CFAColor c2 = int2enum(c1);
+ mRaw->cfa.setColorAt(iPoint2D(x, y), c2);
+ }
}
}
void OrfDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
int iso = 0;
- mRaw->cfa.setCFA(iPoint2D(2,2), CFA_RED, CFA_GREEN, CFA_GREEN, CFA_BLUE);
if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getU32();
+ parseCFA();
+
setMetaData(meta, "", iso);
if (mRootIFD->hasEntryRecursive(OLYMPUSREDMULTIPLIER) &&
diff --git a/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.h
index 3a7a7d038..ba2554869 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/OrfDecoder.h
@@ -25,12 +25,11 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "io/ByteStream.h" // for ByteStream
-#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include "tiff/TiffIFD.h" // for TiffRootIFD (ptr only)
+#include <utility> // for move
namespace rawspeed {
-class ByteStream;
class CameraMetaData;
class Buffer;
@@ -48,8 +47,10 @@ public:
void decodeMetaDataInternal(const CameraMetaData* meta) override;
private:
+ void parseCFA();
+
int getDecoderVersion() const override { return 3; }
- void decodeUncompressed(const ByteStream& s, uint32 w, uint32 h, uint32 size);
+ bool decodeUncompressed(const ByteStream& s, uint32 w, uint32 h, uint32 size);
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.cpp
index b68db8af9..2a4d3658f 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.cpp
@@ -20,16 +20,16 @@
*/
#include "decoders/PefDecoder.h"
-#include "common/Common.h" // for uint32, BitOrder::BitO...
+#include "common/Common.h" // for uint32, BitOrder_MSB
#include "common/Point.h" // for iPoint2D
-#include "decoders/RawDecoderException.h" // for RawDecoderException (p...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/PentaxDecompressor.h" // for PentaxDecompressor
#include "io/ByteStream.h" // for ByteStream
-#include "io/IOException.h" // for IOException
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN
-#include "tiff/TiffEntry.h" // for TiffEntry
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, CFA_BLUE
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_UNDEFINED
#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag::ISOS...
+#include "tiff/TiffTag.h" // for TiffTag, ISOSPEEDRATINGS
+#include <array> // for array
#include <memory> // for unique_ptr
#include <string> // for operator==, string
diff --git a/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.h
index 4a4893377..99b8f3e89 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/PefDecoder.h
@@ -23,7 +23,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.cpp
index 01445b1df..519c58142 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.cpp
@@ -28,13 +28,15 @@
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
#include "io/Endianness.h" // for Endianness, getH...
+#include "metadata/BlackArea.h" // for BlackArea
#include "metadata/Camera.h" // for Camera, Hints
#include "metadata/CameraMetaData.h" // for CameraMetaData
#include "metadata/CameraSensorInfo.h" // for CameraSensorInfo
#include "metadata/ColorFilterArray.h" // for ColorFilterArray
#include "tiff/TiffEntry.h" // for TiffEntry
#include "tiff/TiffIFD.h" // for TiffRootIFD, Tif...
-#include "tiff/TiffTag.h" // for TiffTag::FUJI_RA...
+#include "tiff/TiffTag.h" // for FUJI_RAWIMAGEFUL...
+#include <array> // for array
#include <cassert> // for assert
#include <cstdio> // for size_t
#include <cstring> // for memcmp
@@ -45,10 +47,11 @@
namespace rawspeed {
bool RafDecoder::isRAF(const Buffer* input) {
- static const char magic[] = "FUJIFILMCCD-RAW ";
- static const size_t magic_size = sizeof(magic) - 1; // excluding \0
- const unsigned char* data = input->getData(0, magic_size);
- return 0 == memcmp(&data[0], magic, magic_size);
+ static const std::array<char, 16> magic = {{'F', 'U', 'J', 'I', 'F', 'I', 'L',
+ 'M', 'C', 'C', 'D', '-', 'R', 'A',
+ 'W', ' '}};
+ const unsigned char* data = input->getData(0, magic.size());
+ return 0 == memcmp(data, magic.data(), magic.size());
}
bool RafDecoder::isAppropriateDecoder(const TiffRootIFD* rootIFD,
diff --git a/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.h
index 368ac313c..3821f37e6 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/RafDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFD (ptr only)
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/RawDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/RawDecoder.cpp
index ee9786cdd..ee7a82677 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/RawDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/RawDecoder.cpp
@@ -19,15 +19,15 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "rawspeedconfig.h"
#include "decoders/RawDecoder.h"
-#include "common/Common.h" // for uint32, splitString
+#include "common/Common.h" // for uint32, roundUpD...
#include "common/Point.h" // for iPoint2D, iRecta...
-#include "decoders/RawDecoderException.h" // for ThrowRDE, RawDec...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/Buffer.h" // for Buffer
#include "io/FileIOException.h" // for FileIOException
#include "io/IOException.h" // for IOException
+#include "metadata/BlackArea.h" // for BlackArea
#include "metadata/Camera.h" // for Camera, Hints
#include "metadata/CameraMetaData.h" // for CameraMetaData
#include "metadata/CameraSensorInfo.h" // for CameraSensorInfo
@@ -35,7 +35,9 @@
#include "parsers/TiffParserException.h" // for TiffParserException
#include "tiff/TiffEntry.h" // for TiffEntry
#include "tiff/TiffIFD.h" // for TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag::STRIPOF...
+#include "tiff/TiffTag.h" // for BITSPERSAMPLE
+#include <array> // for array
+#include <cassert> // for assert
#include <string> // for string, basic_st...
#include <vector> // for vector
@@ -85,7 +87,7 @@ void RawDecoder::decodeUncompressed(const TiffIFD *rawIFD, BitOrder order) {
break;
default:
ThrowRDE("Unexpected bits per pixel: %u.", bitPerPixel);
- };
+ }
vector<RawSlice> slices;
slices.reserve(counts->count);
@@ -193,7 +195,11 @@ void RawDecoder::setMetaData(const CameraMetaData* meta, const string& make,
return;
}
- mRaw->cfa = cam->cfa;
+ // Only override CFA with the data from cameras.xml if it actually contained
+ // the CFA.
+ if (cam->cfa.getSize().area() > 0)
+ mRaw->cfa = cam->cfa;
+
mRaw->metadata.canonical_make = cam->canonical_make;
mRaw->metadata.canonical_model = cam->canonical_model;
mRaw->metadata.canonical_alias = cam->canonical_alias;
@@ -222,7 +228,7 @@ void RawDecoder::setMetaData(const CameraMetaData* meta, const string& make,
if (mRaw->blackAreas.empty() && !sensor->mBlackLevelSeparate.empty()) {
auto cfaArea = mRaw->cfa.getSize().area();
if (mRaw->isCFA && cfaArea <= sensor->mBlackLevelSeparate.size()) {
- for (uint32 i = 0; i < cfaArea; i++) {
+ for (auto i = 0UL; i < cfaArea; i++) {
mRaw->blackLevelSeparate[i] = sensor->mBlackLevelSeparate[i];
}
} else if (!mRaw->isCFA && mRaw->getCpp() <= sensor->mBlackLevelSeparate.size()) {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.cpp
index 6a9c0e744..f6bace065 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.cpp
@@ -24,15 +24,17 @@
#include "common/Point.h" // for iPoint2D
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/PanasonicDecompressor.h" // for PanasonicDecompr...
+#include "decompressors/PanasonicDecompressorV5.h" // for PanasonicDecompr...
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
#include "io/Endianness.h" // for Endianness, Endi...
#include "metadata/Camera.h" // for Hints
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, Color...
#include "tiff/TiffEntry.h" // for TiffEntry
-#include "tiff/TiffIFD.h" // for TiffIFD, TiffRoo...
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag...
+#include "tiff/TiffIFD.h" // for TiffRootIFD, Tif...
+#include "tiff/TiffTag.h" // for TiffTag, PANASON...
+#include <array> // for array
#include <cmath> // for fabs
#include <memory> // for unique_ptr
#include <string> // for string, operator==
@@ -76,7 +78,7 @@ RawImage Rw2Decoder::decodeRawInternal() {
if (offsets->count != 1) {
ThrowRDE("Multiple Strips found: %u", offsets->count);
}
- offset = offsets->getU32();
+ uint32 offset = offsets->getU32();
if (!mFile->isValid(offset))
ThrowRDE("Invalid image data offset, cannot decode.");
@@ -95,11 +97,10 @@ RawImage Rw2Decoder::decodeRawInternal() {
mRaw->createData();
u.decode12BitRaw<Endianness::little, false, true>(width, height);
} else {
- // It's using the new .RW2 decoding method
- load_flags = 0;
- // It's using the new .RW2 decoding method
+ uint32 section_split_offset = 0;
PanasonicDecompressor p(mRaw, ByteStream(mFile, offset),
- hints.has("zero_is_not_bad"), load_flags);
+ hints.has("zero_is_not_bad"),
+ section_split_offset);
mRaw->createData();
p.decompress();
}
@@ -112,18 +113,29 @@ RawImage Rw2Decoder::decodeRawInternal() {
ThrowRDE("Multiple Strips found: %u", offsets->count);
}
- offset = offsets->getU32();
+ uint32 offset = offsets->getU32();
- if (!mFile->isValid(offset))
- ThrowRDE("Invalid image data offset, cannot decode.");
+ ByteStream bs(mFile, offset);
+
+ bool v5Processing = raw->hasEntry(PANASONIC_RAWFORMAT) &&
+ raw->getEntry(PANASONIC_RAWFORMAT)->getU16() == 5;
+
+ rawspeed::ushort16 bitsPerSample = 12;
+ if (raw->hasEntry(PANASONIC_BITSPERSAMPLE)) {
+ bitsPerSample = raw->getEntry(PANASONIC_BITSPERSAMPLE)->getU16();
+ }
- // It's using the new .RW2 decoding method
- load_flags = 0x2008;
- // It's using the new .RW2 decoding method
- PanasonicDecompressor p(mRaw, ByteStream(mFile, offset),
- hints.has("zero_is_not_bad"), load_flags);
- mRaw->createData();
- p.decompress();
+ if (v5Processing) {
+ PanasonicDecompressorV5 v5(mRaw, bs, bitsPerSample);
+ mRaw->createData();
+ v5.decompress();
+ } else {
+ uint32 section_split_offset = 0x1FF8;
+ PanasonicDecompressor p(mRaw, bs, hints.has("zero_is_not_bad"),
+ section_split_offset);
+ mRaw->createData();
+ p.decompress();
+ }
}
return mRaw;
diff --git a/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.h b/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.h
index 5f5b4f999..cceb1a949 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/Rw2Decoder.h
@@ -21,12 +21,11 @@
#pragma once
-#include "common/Common.h" // for uint32
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
-#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include "tiff/TiffIFD.h" // for TiffRootIFD (ptr only)
#include <string> // for string
+#include <utility> // for move
namespace rawspeed {
@@ -46,12 +45,10 @@ public:
void checkSupportInternal(const CameraMetaData* meta) override;
protected:
- int getDecoderVersion() const override { return 2; }
+ int getDecoderVersion() const override { return 3; }
private:
std::string guessMode();
- uint32 offset = 0;
- uint32 load_flags = 0;
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decoders/SimpleTiffDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/SimpleTiffDecoder.h
index fecf038ea..c4c85142a 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/SimpleTiffDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/SimpleTiffDecoder.h
@@ -25,7 +25,7 @@
#include "common/Common.h" // for uint32
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffIFD (ptr only), TiffRo...
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.cpp
index 57e1e2449..ca73ed6f0 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.cpp
@@ -20,18 +20,20 @@
*/
#include "decoders/SrwDecoder.h"
-#include "common/Common.h" // for BitOrder::BitOrder_LSB
+#include "common/Common.h" // for uint32, BitOrder_LSB
#include "common/Point.h" // for iPoint2D
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/SamsungV0Decompressor.h" // for SamsungV0Decompressor
#include "decompressors/SamsungV1Decompressor.h" // for SamsungV1Decompressor
#include "decompressors/SamsungV2Decompressor.h" // for SamsungV2Decompressor
+#include "io/Buffer.h" // for Buffer, DataBuffer
#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endiann...
#include "metadata/Camera.h" // for Hints
#include "metadata/CameraMetaData.h" // for CameraMetaData
-#include "tiff/TiffEntry.h" // for TiffEntry
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_LONG
#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag::BITSPERSAMPLE
+#include "tiff/TiffTag.h" // for STRIPOFFSETS, BITSP...
#include <memory> // for unique_ptr
#include <sstream> // for operator<<, ostring...
#include <string> // for string, operator==
diff --git a/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.h
index a1b540f9f..9510608c0 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/SrwDecoder.h
@@ -23,8 +23,8 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffIFD (ptr only), TiffRo...
-#include <algorithm> // for move
#include <string> // for string
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.cpp b/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.cpp
index 7eb575a37..6ff7d82aa 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.cpp
+++ b/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.cpp
@@ -24,13 +24,13 @@
#include "common/Point.h" // for iPoint2D
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/HasselbladDecompressor.h" // for HasselbladDecompre...
+#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/IOException.h" // for IOException
#include "metadata/Camera.h" // for Hints
-#include "metadata/ColorFilterArray.h" // for CFAColor::CFA_GREEN
+#include "metadata/ColorFilterArray.h" // for CFA_GREEN, CFA_BLUE
#include "tiff/TiffEntry.h" // for TiffEntry
#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag::ASSHOTNEU...
+#include "tiff/TiffTag.h" // for ASSHOTNEUTRAL, STR...
#include <memory> // for unique_ptr
#include <string> // for operator==, string
@@ -79,7 +79,7 @@ void ThreefrDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
if (wb->count == 3) {
for (uint32 i = 0; i < 3; i++) {
const float div = wb->getFloat(i);
- if (div == 0.0f)
+ if (div == 0.0F)
ThrowRDE("Can not decode WB, multiplier is zero/");
mRaw->metadata.wbCoeffs[i] = 1.0F / div;
diff --git a/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.h b/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.h
index fc3d03db4..beff7d0d2 100644
--- a/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.h
+++ b/src/external/rawspeed/src/librawspeed/decoders/ThreefrDecoder.h
@@ -24,7 +24,7 @@
#include "common/RawImage.h" // for RawImage
#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
#include "tiff/TiffIFD.h" // for TiffRootIFDOwner
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.cpp
index 8cfe1e17b..18173edc5 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.cpp
@@ -20,7 +20,7 @@
#include "rawspeedconfig.h" // for HAVE_JPEG, HAVE_...
#include "decompressors/AbstractDngDecompressor.h"
-#include "common/Common.h" // for BitOrder::BitOrd...
+#include "common/Common.h" // for BitOrder_LSB
#include "common/Point.h" // for iPoint2D
#include "common/RawImage.h" // for RawImageData
#include "decoders/RawDecoderException.h" // for RawDecoderException
@@ -28,11 +28,10 @@
#include "decompressors/JpegDecompressor.h" // for JpegDecompressor
#include "decompressors/LJpegDecompressor.h" // for LJpegDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
-#include "io/Buffer.h" // for Buffer (ptr only)
+#include "decompressors/VC5Decompressor.h" // for VC5Decompressor
#include "io/ByteStream.h" // for ByteStream
#include "io/Endianness.h" // for Endianness, Endi...
-#include "io/IOException.h" // for IOException
-#include "tiff/TiffIFD.h" // for getTiffByteOrder
+#include "io/IOException.h" // for IOException, Thr...
#include <cassert> // for assert
#include <cstdio> // for size_t
#include <limits> // for numeric_limits
@@ -111,7 +110,7 @@ void AbstractDngDecompressor::decompressThreaded(
/* Deflate compression */
} else if (compression == 8) {
#ifdef HAVE_ZLIB
- std::unique_ptr<unsigned char[]> uBuffer;
+ std::unique_ptr<unsigned char[]> uBuffer; // NOLINT
for (size_t i = t->start; i < t->end && i < slices.size(); i++) {
auto e = &slices[i];
@@ -130,6 +129,19 @@ void AbstractDngDecompressor::decompressThreaded(
"ZLIB is not present! Deflate compression will not be supported!"
ThrowRDE("deflate support is disabled.");
#endif
+ /* VC-5 */
+ } else if (compression == 9) {
+ for (size_t i = t->start; i < t->end && i < slices.size(); i++) {
+ auto e = &slices[i];
+ VC5Decompressor d(e->bs, mRaw);
+ try {
+ d.decode(e->offX, e->offY, e->width, e->height);
+ } catch (RawDecoderException& err) {
+ mRaw->setError(err.what());
+ } catch (IOException& err) {
+ mRaw->setError(err.what());
+ }
+ }
/* Lossy DNG */
} else if (compression == 0x884c) {
#ifdef HAVE_JPEG
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.h
index 44b6545ea..626ffeaa6 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.h
@@ -21,6 +21,7 @@
#pragma once
#include "common/Common.h" // for uint32
+#include "common/Point.h" // for iPoint2D
#include "decompressors/AbstractParallelizedDecompressor.h" // for Abstract...
#include "io/ByteStream.h" // for ByteStream
#include <cassert> // for assert
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/AbstractHuffmanTable.h b/src/external/rawspeed/src/librawspeed/decompressors/AbstractHuffmanTable.h
new file mode 100644
index 000000000..a62c1e9a3
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/AbstractHuffmanTable.h
@@ -0,0 +1,247 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017 Axel Waggershauser
+ Copyright (C) 2017-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
+*/
+
+#pragma once
+
+#include "common/Common.h" // for uchar8, uint32, ushort16
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "io/Buffer.h" // for Buffer
+#include <algorithm> // for copy, adjacent_find, max_e...
+#include <cassert> // for assert
+#include <cstddef> // for size_t
+#include <functional> // for less, less_equal
+#include <iterator> // for back_insert_iterator, back...
+#include <numeric> // for accumulate
+#include <vector> // for vector, operator==
+
+namespace rawspeed {
+
+class AbstractHuffmanTable {
+public:
+ struct CodeSymbol final {
+ ushort16 code; // the code (bit pattern found inside the stream)
+ uchar8 code_len; // the code length in bits, valid values are 1..16
+
+ CodeSymbol() = default;
+
+ CodeSymbol(ushort16 code_, uchar8 code_len_)
+ : code(code_), code_len(code_len_) {
+ assert(code_len > 0);
+ assert(code_len <= 16);
+ assert(code <= ((1U << code_len) - 1U));
+ }
+
+ static bool HaveCommonPrefix(const CodeSymbol& symbol,
+ const CodeSymbol& partial) {
+ assert(partial.code_len <= symbol.code_len);
+
+ auto getNHighBits = [](const CodeSymbol& s, unsigned bits) -> ushort16 {
+ const auto shift = s.code_len - bits;
+ return s.code >> shift;
+ };
+
+ const auto s0 = getNHighBits(symbol, partial.code_len);
+ const auto s1 = partial.code;
+
+ return s0 == s1;
+ }
+ };
+
+protected:
+ inline size_t __attribute__((pure)) maxCodePlusDiffLength() const {
+ return nCodesPerLength.size() - 1 +
+ *(std::max_element(codeValues.cbegin(), codeValues.cend()));
+ }
+
+ // These two fields directly represent the contents of a JPEG DHT field
+
+ // 1. The number of codes there are per bit length, this is index 1 based.
+ // (there are always 0 codes of length 0)
+ std::vector<unsigned int> nCodesPerLength; // index is length of code
+
+ inline unsigned int __attribute__((pure)) maxCodesCount() const {
+ return std::accumulate(nCodesPerLength.begin(), nCodesPerLength.end(), 0U);
+ }
+
+ // 2. This is the actual huffman encoded data, i.e. the 'alphabet'. Each value
+ // is the number of bits following the code that encode the difference to the
+ // last pixel. Valid values are in the range 0..16.
+ // signExtended() is used to decode the difference bits to a signed int.
+ std::vector<uchar8> codeValues; // index is just sequential number
+
+ static void VerifyCodeSymbols(const std::vector<CodeSymbol>& symbols) {
+#ifndef NDEBUG
+ // The code symbols are ordered so that all the code values are strictly
+ // increasing and code lenghts are not decreasing.
+ const auto symbolSort = [](const CodeSymbol& lhs,
+ const CodeSymbol& rhs) -> bool {
+ return std::less<>()(lhs.code, rhs.code) &&
+ std::less_equal<>()(lhs.code_len, rhs.code_len);
+ };
+#endif
+ assert(std::adjacent_find(symbols.cbegin(), symbols.cend(),
+ [&symbolSort](const CodeSymbol& lhs,
+ const CodeSymbol& rhs) -> bool {
+ return !symbolSort(lhs, rhs);
+ }) == symbols.cend() &&
+ "all code symbols are globally ordered");
+
+ // No two symbols should have the same prefix (high bytes)
+ // Only analyze the lower triangular matrix, excluding diagonal
+ for (auto sId = 0UL; sId < symbols.size(); sId++) {
+ for (auto pId = 0UL; pId < sId; pId++)
+ assert(!CodeSymbol::HaveCommonPrefix(symbols[sId], symbols[pId]));
+ }
+ }
+
+ std::vector<CodeSymbol> generateCodeSymbols() const {
+ std::vector<CodeSymbol> symbols;
+
+ assert(!nCodesPerLength.empty());
+ assert(maxCodesCount() > 0);
+
+ const auto maxCodeLength = nCodesPerLength.size() - 1U;
+ assert(codeValues.size() == maxCodesCount());
+
+ // reserve all the memory. avoids lots of small allocs
+ symbols.reserve(maxCodesCount());
+
+ // Figure C.1: make table of Huffman code length for each symbol
+ // Figure C.2: generate the codes themselves
+ uint32 code = 0;
+ for (unsigned int l = 1; l <= maxCodeLength; ++l) {
+ for (unsigned int i = 0; i < nCodesPerLength[l]; ++i) {
+ assert(code <= 0xffff);
+
+ symbols.emplace_back(code, l);
+ code++;
+ }
+
+ code <<= 1;
+ }
+
+ assert(symbols.size() == maxCodesCount());
+ VerifyCodeSymbols(symbols);
+
+ return symbols;
+ }
+
+public:
+ bool operator==(const AbstractHuffmanTable& other) const {
+ return nCodesPerLength == other.nCodesPerLength &&
+ codeValues == other.codeValues;
+ }
+
+ uint32 setNCodesPerLength(const Buffer& data) {
+ assert(data.getSize() == 16);
+
+ nCodesPerLength.resize(17, 0);
+ std::copy(data.begin(), data.end(), &nCodesPerLength[1]);
+ assert(nCodesPerLength[0] == 0);
+
+ // trim empty entries from the codes per length table on the right
+ while (!nCodesPerLength.empty() && nCodesPerLength.back() == 0)
+ nCodesPerLength.pop_back();
+
+ if (nCodesPerLength.empty())
+ ThrowRDE("Codes-per-length table is empty");
+
+ assert(nCodesPerLength.back() > 0);
+
+ const auto count = maxCodesCount();
+ assert(count > 0);
+
+ if (count > 162)
+ ThrowRDE("Too big code-values table");
+
+ // We are at the Root node, len is 1, there are two possible child Nodes
+ unsigned maxCodes = 2;
+
+ for (auto codeLen = 1UL; codeLen < nCodesPerLength.size(); codeLen++) {
+ // we have codeLen bits. make sure that that code count can actually fit
+ // E.g. for len 1 we could have two codes: 0b0 and 0b1
+ // (but in that case there can be no other codes (with higher lenghts))
+ const auto maxCodesInCurrLen = (1U << codeLen);
+ const auto nCodes = nCodesPerLength[codeLen];
+ if (nCodes > maxCodesInCurrLen) {
+ ThrowRDE("Corrupt Huffman. Can never have %u codes in %lu-bit len",
+ nCodes, codeLen);
+ }
+
+ // Also, check that we actually can have this much leafs for this lenght
+ if (nCodes > maxCodes) {
+ ThrowRDE(
+ "Corrupt Huffman. Can only fit %u out of %u codes in %lu-bit len",
+ maxCodes, nCodes, codeLen);
+ }
+
+ // There are nCodes leafs on this level, and those can not be branches
+ maxCodes -= nCodes;
+ // On the next level, rest can be branches, and can have two child Nodes
+ maxCodes *= 2;
+ }
+
+ return count;
+ }
+
+ void setCodeValues(const Buffer& data) {
+ // spec says max 16 but Hasselblad ignores that -> allow 17
+ // Canon's old CRW really ignores this ...
+ assert(data.getSize() <= 162);
+ assert(data.getSize() == maxCodesCount());
+
+ codeValues.clear();
+ codeValues.reserve(maxCodesCount());
+ std::copy(data.begin(), data.end(), std::back_inserter(codeValues));
+ assert(codeValues.size() == maxCodesCount());
+
+ for (const auto cValue : codeValues) {
+ if (cValue > 16)
+ ThrowRDE("Corrupt Huffman. Code value %u is bigger than 16", cValue);
+ }
+ }
+
+ // WARNING: the caller should check that len != 0 before calling the function
+ inline static int __attribute__((const))
+ signExtended(uint32 diff, uint32 len) {
+ int32 ret = diff;
+#if 0
+#define _X(x) (1 << x) - 1
+ constexpr static int offset[16] = {
+ 0, _X(1), _X(2), _X(3), _X(4), _X(5), _X(6), _X(7),
+ _X(8), _X(9), _X(10), _X(11), _X(12), _X(13), _X(14), _X(15)};
+#undef _X
+ if ((diff & (1 << (len - 1))) == 0)
+ ret -= offset[len];
+#else
+ if ((diff & (1 << (len - 1))) == 0)
+ ret -= (1 << len) - 1;
+#endif
+ return ret;
+ }
+};
+
+inline bool operator==(const AbstractHuffmanTable::CodeSymbol& lhs,
+ const AbstractHuffmanTable::CodeSymbol& rhs) {
+ return lhs.code == rhs.code && lhs.code_len == rhs.code_len;
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp
index 442b6c9a7..a56c3056d 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp
@@ -21,15 +21,18 @@
*/
#include "decompressors/AbstractLJpegDecompressor.h"
-#include "common/Common.h" // for uint32, make_unique, uchar8
-#include "common/Point.h" // for iPoint2D
-#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "decompressors/HuffmanTable.h" // for HuffmanTable
-#include "io/ByteStream.h" // for ByteStream
-#include <array> // for array
-#include <memory> // for unique_ptr, allocator
-#include <utility> // for move
-#include <vector> // for vector
+#include "common/Common.h" // for uint32, uchar8
+#include "common/Point.h" // for iPoint2D
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/AbstractHuffmanTable.h" // for AbstractHuffmanTable
+#include "decompressors/HuffmanTable.h" // for HuffmanTable, Huffma...
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endianne...
+#include <array> // for array
+#include <cassert> // for assert
+#include <memory> // for unique_ptr, make_unique
+#include <utility> // for move
+#include <vector> // for vector
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.h
index 74a7941af..53a6d8d46 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/AbstractLJpegDecompressor.h
@@ -26,13 +26,10 @@
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
#include "decompressors/HuffmanTable.h" // for HuffmanTable
-#include "io/Buffer.h" // for Buffer, Buffer::size_type
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for getHostEndianness, Endiannes...
-#include <array> // for array
-#include <memory> // for unique_ptr
-#include <utility> // for move
-#include <vector> // for vector
+#include <array> // for array
+#include <memory> // for unique_ptr
+#include <vector> // for vector
/*
* The following enum and two structs are stolen from the IJG JPEG library
@@ -118,20 +115,20 @@ struct JpegComponentInfo {
* These values are fixed over the whole image.
* They are read from the SOF marker.
*/
- uint32 componentId = -1; /* identifier for this component (0..255) */
+ uint32 componentId = ~0U; /* identifier for this component (0..255) */
/*
* Huffman table selector (0..3). The value may vary
* between scans. It is read from the SOS marker.
*/
- uint32 dcTblNo = -1;
- uint32 superH = -1; // Horizontal Supersampling
- uint32 superV = -1; // Vertical Supersampling
+ uint32 dcTblNo = ~0U;
+ uint32 superH = ~0U; // Horizontal Supersampling
+ uint32 superV = ~0U; // Vertical Supersampling
};
class SOFInfo {
public:
- JpegComponentInfo compInfo[4];
+ std::array<JpegComponentInfo, 4> compInfo;
uint32 w = 0; // Width
uint32 h = 0; // Height
uint32 cps = 0; // Components
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/AbstractParallelizedDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/AbstractParallelizedDecompressor.h
index 36fbdffd8..d9dbd4d9e 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/AbstractParallelizedDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/AbstractParallelizedDecompressor.h
@@ -73,7 +73,7 @@ public:
return nullptr;
}
- uint32 taskNo = -1;
+ uint32 taskNo = ~0U;
const uint32 tasksTotal;
uint32 start = 0;
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/BinaryHuffmanTree.h b/src/external/rawspeed/src/librawspeed/decompressors/BinaryHuffmanTree.h
new file mode 100644
index 000000000..3660e1247
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/BinaryHuffmanTree.h
@@ -0,0 +1,237 @@
+/*
+ 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
+*/
+
+#pragma once
+
+#include <cassert> // for assert
+#include <initializer_list> // IWYU pragma: keep
+#include <memory> // for unique_ptr
+#include <vector> // for vector
+
+namespace rawspeed {
+
+template <typename T>
+class BinaryHuffmanTree final /* : public BinarySearchTree */ {
+public:
+ struct Branch;
+ struct Leaf;
+
+ struct Node {
+ enum class Type { Branch, Leaf };
+
+ explicit virtual operator Type() const = 0;
+
+ Branch& getAsBranch() {
+ assert(Node::Type::Branch == static_cast<Node::Type>(*this));
+ return static_cast<Branch&>(*this);
+ }
+
+ Leaf& getAsLeaf() {
+ assert(Node::Type::Leaf == static_cast<Node::Type>(*this));
+ return static_cast<Leaf&>(*this);
+ }
+
+ virtual ~Node() = default;
+ };
+
+ struct Branch final : public Node {
+ explicit operator typename Node::Type() const override {
+ return Node::Type::Branch;
+ }
+
+ std::unique_ptr<Node> zero;
+ std::unique_ptr<Node> one;
+
+ template <typename Lambda> bool forEachNode(Lambda l) const;
+ template <typename Lambda> bool forEachNode(Lambda l);
+
+ bool hasLeafs() const;
+
+ static bool pruneLeaflessBranches(std::unique_ptr<Node>* n);
+ };
+
+ struct Leaf final : public Node {
+ explicit operator typename Node::Type() const override {
+ return Node::Type::Leaf;
+ }
+
+ T value;
+
+ Leaf() = default;
+
+ explicit Leaf(T value_) : value(value_) {}
+ };
+
+ std::unique_ptr<Node> root;
+
+ std::vector<Branch*> getAllBranchesOfDepth(int depth);
+ std::vector<std::unique_ptr<Node>*> getAllVacantNodesAtDepth(int depth);
+ void pruneLeaflessBranches();
+};
+
+template <typename T>
+template <typename Lambda>
+bool BinaryHuffmanTree<T>::Branch::forEachNode(Lambda l) const {
+ bool done = false;
+ // NOTE: The order *IS* important! Left to right, zero to one!
+ for (const auto* node : {&zero, &one}) {
+ done = l(node);
+ if (done)
+ return done;
+ }
+ return done;
+}
+
+template <typename T>
+template <typename Lambda>
+bool BinaryHuffmanTree<T>::Branch::forEachNode(Lambda l) {
+ bool done = false;
+ // NOTE: The order *IS* important! Left to right, zero to one!
+ for (auto* node : {&zero, &one}) {
+ done = l(node);
+ if (done)
+ return done;
+ }
+ return done;
+}
+
+template <typename T> bool BinaryHuffmanTree<T>::Branch::hasLeafs() const {
+ return forEachNode([](const std::unique_ptr<Node>* n) {
+ assert(n);
+ if (!(*n)) // If the node is empty, then it certainly does not have leafs
+ return false;
+ return Node::Type::Leaf == static_cast<typename Node::Type>(**n);
+ });
+}
+
+template <typename T>
+bool BinaryHuffmanTree<T>::Branch::pruneLeaflessBranches(
+ std::unique_ptr<Node>* top) {
+ if (!top)
+ return false;
+
+ bool foundLeafs = false; // Any leafs in this branch?
+ (*top)->getAsBranch().forEachNode([&foundLeafs](std::unique_ptr<Node>* n) {
+ assert(n);
+ if (!(*n))
+ return false; // Nothing to do here, node is empty already, keep going.
+ switch (static_cast<typename Node::Type>(**n)) {
+ case Node::Type::Branch:
+ // Recurse. Any leafs in this branch?
+ if (Branch::pruneLeaflessBranches(n))
+ foundLeafs = true;
+ else
+ n->reset(); // Aha, dead branch, prune it!
+ break;
+ case Node::Type::Leaf:
+ foundLeafs = true; // Ok, this is a Leaf, great.
+ break;
+ }
+ return false; // keep going.
+ });
+
+ if (!foundLeafs)
+ top->reset();
+
+ return foundLeafs;
+}
+
+template <typename T>
+std::vector<typename BinaryHuffmanTree<T>::Branch*>
+BinaryHuffmanTree<T>::getAllBranchesOfDepth(int depth) {
+ assert(depth >= 0);
+
+ if (0 == depth) {
+ // The root (depth == 0) is is special, and is *always* a Branch.
+ if (!root)
+ root = std::make_unique<Branch>();
+ return {&root->getAsBranch()};
+ }
+
+ // Recursively get all branches of previous depth
+ auto prevBranches = getAllBranchesOfDepth(depth - 1);
+
+ // Early return in case of no branches on previous depth
+ if (prevBranches.empty())
+ return {};
+
+ // We will have at most twice as much branches as at the previous depth.
+ decltype(prevBranches) branches;
+ branches.reserve(2U * prevBranches.size());
+
+ for (const auto& prevBranch : prevBranches) {
+ assert(prevBranch);
+
+ prevBranch->forEachNode([&branches](std::unique_ptr<Node>* n) {
+ assert(n);
+ // If the Node is vacant, make it a branch.
+ // The user was supposed to create all the required Leafs before.
+ // We shall prune Leaf-less branches at the end
+ if (!(*n))
+ *n = std::make_unique<Branch>();
+ // If this is a branch, add it to the list.
+ if (Node::Type::Branch == static_cast<typename Node::Type>(**n))
+ branches.emplace_back(&((*n)->getAsBranch()));
+ return false; // keep going;
+ });
+ }
+ assert(branches.size() <= 2U * prevBranches.size());
+
+ return branches;
+}
+
+template <typename T>
+std::vector<std::unique_ptr<typename BinaryHuffmanTree<T>::Node>*>
+BinaryHuffmanTree<T>::getAllVacantNodesAtDepth(int depth) {
+ assert(depth > 0);
+
+ // Get all branches of previous depth
+ auto prevBranches = getAllBranchesOfDepth(depth - 1);
+
+ // Early return in case of no branches on previous depth
+ if (prevBranches.empty())
+ return {};
+
+ // We will have at most two nodes per each branch on the previous depth.
+ std::vector<std::unique_ptr<BinaryHuffmanTree<T>::Node>*> nodes;
+ nodes.reserve(2U * prevBranches.size());
+
+ for (const auto& prevBranch : prevBranches) {
+ assert(prevBranch);
+
+ auto& b = prevBranch->getAsBranch();
+
+ b.forEachNode([&nodes](std::unique_ptr<Node>* n) {
+ assert(n);
+ if (!(*n)) // If there is no node already, then record it.
+ nodes.emplace_back(n);
+ return false; // keep going;
+ });
+ }
+ assert(nodes.size() <= 2U * prevBranches.size());
+
+ return nodes;
+}
+
+template <typename T> void BinaryHuffmanTree<T>::pruneLeaflessBranches() {
+ Branch::pruneLeaflessBranches(&root);
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/CMakeLists.txt b/src/external/rawspeed/src/librawspeed/decompressors/CMakeLists.txt
index 48b12413a..fa48ebaf8 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/CMakeLists.txt
+++ b/src/external/rawspeed/src/librawspeed/decompressors/CMakeLists.txt
@@ -2,11 +2,13 @@ FILE(GLOB SOURCES
"AbstractDecompressor.h"
"AbstractDngDecompressor.cpp"
"AbstractDngDecompressor.h"
+ "AbstractHuffmanTable.h"
"AbstractLJpegDecompressor.cpp"
"AbstractLJpegDecompressor.h"
"AbstractParallelizedDecompressor.cpp"
"AbstractParallelizedDecompressor.h"
"AbstractSamsungDecompressor.h"
+ "BinaryHuffmanTree.h"
"Cr2Decompressor.cpp"
"Cr2Decompressor.h"
"CrwDecompressor.cpp"
@@ -18,6 +20,10 @@ FILE(GLOB SOURCES
"HasselbladDecompressor.cpp"
"HasselbladDecompressor.h"
"HuffmanTable.h"
+ "HuffmanTableLUT.h"
+ "HuffmanTableLookup.h"
+ "HuffmanTableTree.h"
+ "HuffmanTableVector.h"
"JpegDecompressor.cpp"
"JpegDecompressor.h"
"KodakDecompressor.cpp"
@@ -30,8 +36,12 @@ FILE(GLOB SOURCES
"OlympusDecompressor.h"
"PanasonicDecompressor.cpp"
"PanasonicDecompressor.h"
+ "PanasonicDecompressorV5.cpp"
+ "PanasonicDecompressorV5.h"
"PentaxDecompressor.cpp"
"PentaxDecompressor.h"
+ "PhaseOneDecompressor.cpp"
+ "PhaseOneDecompressor.h"
"SamsungV0Decompressor.cpp"
"SamsungV0Decompressor.h"
"SamsungV1Decompressor.cpp"
@@ -44,6 +54,8 @@ FILE(GLOB SOURCES
"SonyArw2Decompressor.h"
"UncompressedDecompressor.cpp"
"UncompressedDecompressor.h"
+ "VC5Decompressor.cpp"
+ "VC5Decompressor.h"
)
target_sources(rawspeed PRIVATE
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.cpp
index e43a0ed54..bce287cfb 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.cpp
@@ -21,19 +21,21 @@
*/
#include "decompressors/Cr2Decompressor.h"
-#include "common/Common.h" // for uint32, unroll_loop, ushort16
-#include "common/Point.h" // for iPoint2D
+#include "common/Common.h" // for unroll_loop, uint32, ushort16
+#include "common/Point.h" // for iPoint2D, iPoint2D::area_type
#include "common/RawImage.h" // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "io/BitPumpJPEG.h" // for BitPumpJPEG
-#include <algorithm> // for move, copy_n
+#include "io/BitPumpJPEG.h" // for BitPumpJPEG, BitStream<>::...
+#include <algorithm> // for copy_n
#include <cassert> // for assert
-#include <numeric> // for accumulate
+#include <initializer_list> // for initializer_list
using std::copy_n;
namespace rawspeed {
+class ByteStream;
+
Cr2Decompressor::Cr2Decompressor(const ByteStream& bs, const RawImage& img)
: AbstractLJpegDecompressor(bs, img) {
if (mRaw->getDataType() != TYPE_USHORT16)
@@ -206,6 +208,9 @@ void Cr2Decompressor::decodeN_X_Y()
if (X_S_F == 1) {
if (destX + sliceWidth > static_cast<unsigned>(mRaw->dim.x))
ThrowRDE("Bad slice width / frame size / image size combination.");
+ if (((sliceId + 1) == slicing.numSlices) &&
+ ((destX + sliceWidth) < static_cast<unsigned>(mRaw->dim.x)))
+ ThrowRDE("Unsufficient slices - do not fill the entire image");
} else {
// FIXME.
}
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.h
index 4607f3ed8..9165212c6 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/Cr2Decompressor.h
@@ -21,18 +21,15 @@
#pragma once
-#include "common/Common.h" // ushort16
+#include "common/Common.h" // for ushort16
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/AbstractLJpegDecompressor.h" // for AbstractLJpegDe...
-#include "io/Buffer.h" // for Buffer, Buffer:...
-#include "io/ByteStream.h" // for ByteStream
#include <cassert> // for assert
namespace rawspeed {
+class ByteStream;
class RawImage;
-class Cr2Decompressor;
-// Decompresses Lossless JPEGs, with 2-4 components and optional X/Y subsampling
class Cr2Slicing {
int numSlices = 0;
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.cpp
index ce9ccd874..6457568cb 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.cpp
@@ -21,17 +21,16 @@
*/
#include "decompressors/CrwDecompressor.h"
-#include "common/Common.h" // for uint32, ushort16, uchar8
+#include "common/Common.h" // for uint32, uchar8, ushort16
#include "common/Point.h" // for iPoint2D
#include "common/RawImage.h" // for RawImage, RawImageData
-#include "decoders/RawDecoderException.h" // for RawDecoderException (ptr o...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/HuffmanTable.h" // for HuffmanTable
#include "io/BitPumpJPEG.h" // for BitPumpJPEG, BitStream<>::...
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include <algorithm> // for min
-#include <array> // for array
-#include <memory> // for make_unique
+#include <array> // for array, array<>::value_type
+#include <cassert> // for assert
using std::array;
@@ -85,32 +84,32 @@ CrwDecompressor::crw_hts CrwDecompressor::initHuffTables(uint32 table) {
ThrowRDE("Wrong table number: %u", table);
// NCodesPerLength
- static const uchar8 first_tree_ncpl[3][16] = {
+ static const std::array<std::array<uchar8, 16>, 3> first_tree_ncpl = {{
{0, 1, 4, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 2, 2, 3, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 6, 3, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- };
+ }};
- static const uchar8 first_tree_len[3][13] = {
+ static const std::array<std::array<uchar8, 13>, 3> first_tree_len = {{
{0x4, 0x3, 0x5, 0x6, 0x2, 0x7, 0x1, 0x8, 0x9, 0x0, 0xa, 0xb, 0xf},
{0x3, 0x2, 0x4, 0x1, 0x5, 0x0, 0x6, 0x7, 0x9, 0x8, 0xa, 0xb, 0xf},
{0x6, 0x5, 0x7, 0x4, 0x8, 0x3, 0x9, 0x2, 0x0, 0xa, 0x1, 0xb, 0xf},
- };
+ }};
- static const uchar8 first_tree_index[3][13] = {
+ static const std::array<std::array<uchar8, 13>, 3> first_tree_index = {{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf},
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf},
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf},
- };
+ }};
// NCodesPerLength
- static const uchar8 second_tree_ncpl[3][16] = {
+ static const std::array<std::array<uchar8, 16>, 3> second_tree_ncpl = {{
{0, 2, 2, 2, 1, 4, 2, 1, 2, 5, 1, 1, 0, 0, 0, 139},
{0, 2, 2, 1, 4, 1, 4, 1, 3, 3, 1, 0, 0, 0, 0, 140},
{0, 0, 6, 2, 1, 3, 3, 2, 5, 1, 2, 2, 8, 10, 0, 117},
- };
+ }};
- static const uchar8 second_tree_len[3][164] = {
+ static const std::array<std::array<uchar8, 164>, 3> second_tree_len = {{
{0x3, 0x4, 0x2, 0x5, 0x1, 0x6, 0x7, 0x8, 0x2, 0x3, 0x1, 0x4, 0x9, 0x5,
0x2, 0x0, 0x1, 0x6, 0xa, 0x0, 0x3, 0x7, 0x4, 0x1, 0x2, 0x8, 0x9, 0x3,
0x5, 0x1, 0x4, 0x2, 0x5, 0x1, 0x6, 0x7, 0x8, 0x9, 0x9, 0x6, 0xa, 0x9,
@@ -147,9 +146,9 @@ CrwDecompressor::crw_hts CrwDecompressor::initHuffTables(uint32 table) {
0x5, 0x2, 0x3, 0x5, 0x2, 0x4, 0x4, 0xa, 0x4, 0x5, 0x3, 0x2, 0x1, 0x5,
0x3, 0xa, 0x4, 0xa, 0x2, 0x1, 0x4, 0x1, 0x3, 0x3, 0xa, 0x3, 0x2, 0x2,
0x1, 0x3, 0x2, 0x1, 0x1, 0x3, 0x2, 0x1, 0xf, 0xf},
- };
+ }};
- static const uchar8 second_tree_index[3][164] = {
+ static const std::array<std::array<uchar8, 164>, 3> second_tree_index = {{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1,
0x2, 0x0, 0x2, 0x1, 0x0, 0xf, 0x2, 0x1, 0x2, 0x3, 0x3, 0x1, 0x1, 0x3,
0x2, 0x4, 0x3, 0x4, 0x3, 0x5, 0x3, 0x3, 0x3, 0x2, 0x7, 0x2, 0x1, 0x3,
@@ -186,13 +185,17 @@ CrwDecompressor::crw_hts CrwDecompressor::initHuffTables(uint32 table) {
0x8, 0x6, 0xf, 0xc, 0xb, 0xa, 0x8, 0xb, 0x6, 0xa, 0xb, 0xd, 0x8, 0xe,
0xd, 0xa, 0xc, 0xc, 0xf, 0xb, 0xe, 0xd, 0x8, 0x6, 0xe, 0xc, 0xe, 0x8,
0xf, 0xa, 0xc, 0xa, 0xc, 0xe, 0xa, 0xe, 0xf, 0xf},
- };
+ }};
array<array<HuffmanTable, 2>, 2> mHuff = {{
- {{makeDecoder(first_tree_ncpl[table], first_tree_len[table]),
- makeDecoder(first_tree_ncpl[table], first_tree_index[table])}},
- {{makeDecoder(second_tree_ncpl[table], second_tree_len[table]),
- makeDecoder(second_tree_ncpl[table], second_tree_index[table])}},
+ {{makeDecoder(first_tree_ncpl[table].data(),
+ first_tree_len[table].data()),
+ makeDecoder(first_tree_ncpl[table].data(),
+ first_tree_index[table].data())}},
+ {{makeDecoder(second_tree_ncpl[table].data(),
+ second_tree_len[table].data()),
+ makeDecoder(second_tree_ncpl[table].data(),
+ second_tree_index[table].data())}},
}};
return mHuff;
@@ -224,6 +227,7 @@ inline void CrwDecompressor::decodeBlock(std::array<int, 64>* diffBuf,
continue;
int diff = lPump->getBits(len);
+ iPump->fill(len);
iPump->skipBits(len);
if (i >= 64)
@@ -255,7 +259,7 @@ void CrwDecompressor::decompress() {
BitPumpJPEG iPump(rawInput);
int carry = 0;
- int base[2];
+ std::array<int, 2> base;
uint32 j = 0;
ushort16* dest = nullptr;
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.h
index f67aca04e..2f10ff9e7 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/CrwDecompressor.h
@@ -22,15 +22,13 @@
#pragma once
-#include "common/Common.h" // for uint32, uchar8
+#include "common/Common.h" // for uchar8, uint32
#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
#include "decompressors/HuffmanTable.h" // for HuffmanTable
#include "io/BitPumpJPEG.h" // for BitPumpJPEG
-#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
#include <array> // for array
-#include <memory> // for unique_ptr
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.cpp
index 9553bd9f8..a996c856b 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.cpp
@@ -24,7 +24,6 @@
#include "decompressors/DeflateDecompressor.h"
#include "common/Common.h" // for uint32, ushort16
-#include "common/Point.h" // for iPoint2D
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/Endianness.h" // for getHostEndianness, Endiann...
#include <cassert> // for assert
@@ -40,7 +39,10 @@ static inline void decodeFPDeltaRow(unsigned char* src, unsigned char* dst,
unsigned int bytesps, int factor) {
// DecodeDeltaBytes
for (size_t col = factor; col < realTileWidth * bytesps; ++col) {
- src[col] += src[col - factor];
+ // Yes, this is correct, and is symmetrical with EncodeDeltaBytes in
+ // hdrmerge, and they both combined are lossless.
+ // This is indeed working in modulo-2^n arighmetics.
+ src[col] = static_cast<unsigned char>(src[col] + src[col - factor]);
}
// Reorder bytes into the image
// 16 and 32-bit versions depend on local architecture, 24-bit does not
@@ -184,13 +186,15 @@ static inline void expandFP24(unsigned char* dst, int width) {
}
}
-void DeflateDecompressor::decode(std::unique_ptr<unsigned char[]>* uBuffer,
- int tileWidthMax, int tileHeightMax, int width,
- int height, uint32 offX, uint32 offY) {
+void DeflateDecompressor::decode(
+ std::unique_ptr<unsigned char[]>* uBuffer, // NOLINT
+ int tileWidthMax, int tileHeightMax, int width, int height, uint32 offX,
+ uint32 offY) {
uLongf dstLen = sizeof(float) * tileWidthMax * tileHeightMax;
if (!uBuffer->get())
- *uBuffer = std::unique_ptr<unsigned char[]>(new unsigned char[dstLen]);
+ *uBuffer =
+ std::unique_ptr<unsigned char[]>(new unsigned char[dstLen]); // NOLINT
const auto cSize = input.getRemainSize();
const unsigned char* cBuffer = input.getData(cSize);
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.h
index 514110c3b..b2cc1a3d7 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/DeflateDecompressor.h
@@ -20,14 +20,13 @@
#pragma once
-#include "rawspeedconfig.h"
+#include "rawspeedconfig.h" // for HAVE_ZLIB
#ifdef HAVE_ZLIB
-#include "common/Common.h" // for getHostEndianness, uint32, Endianness::big
-#include "common/RawImage.h" // for RawImage
+#include "common/Common.h" // for uint32
+#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
-#include "io/Buffer.h" // for Buffer, Buffer::size_type
#include "io/ByteStream.h" // for ByteStream
#include <memory> // for unique_ptr
#include <utility> // for move
@@ -45,9 +44,9 @@ public:
int bps_)
: input(std::move(bs)), mRaw(img), predictor(predictor_), bps(bps_) {}
- void decode(std::unique_ptr<unsigned char[]>* uBuffer, int tileWidthMax,
- int tileHeightMax, int width, int height, uint32 offX,
- uint32 offY);
+ void decode(std::unique_ptr<unsigned char[]>* uBuffer, // NOLINT
+ int tileWidthMax, int tileHeightMax, int width, int height,
+ uint32 offX, uint32 offY);
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.cpp
index 44459419a..1b1162047 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.cpp
@@ -22,16 +22,17 @@
*/
#include "decompressors/FujiDecompressor.h"
-#include "common/Common.h" // for roundUpDiv...
+#include "common/Common.h" // for ushort16
+#include "common/Point.h" // for iPoint2D
#include "common/RawImage.h" // for RawImage
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/AbstractParallelizedDecompressor.h" // for RawDecom...
#include "io/Endianness.h" // for Endianness
-#include "metadata/ColorFilterArray.h" // for CFAColor...
+#include "metadata/ColorFilterArray.h" // for CFA_BLUE
#include <algorithm> // for fill, min
-#include <cstdlib> // for abs
+#include <cmath> // for abs
+#include <cstdlib> // for abs, size_t
#include <cstring> // for memcpy
-// IWYU pragma: no_include <bits/std_abs.h>
namespace rawspeed {
@@ -172,9 +173,9 @@ template <typename T>
void FujiDecompressor::copy_line(fuji_compressed_block* info,
const FujiStrip& strip, int cur_line,
T&& idx) const {
- ushort16* lineBufB[3];
- ushort16* lineBufG[6];
- ushort16* lineBufR[3];
+ std::array<ushort16*, 3> lineBufB;
+ std::array<ushort16*, 6> lineBufG;
+ std::array<ushort16*, 3> lineBufR;
for (int i = 0; i < 3; i++) {
lineBufR[i] = info->linebuf[_R2 + i] + 1;
@@ -233,7 +234,8 @@ void FujiDecompressor::copy_line_to_bayer(fuji_compressed_block* info,
copy_line(info, strip, cur_line, index);
}
-void FujiDecompressor::fuji_zerobits(BitPumpMSB* pump, int* count) const {
+inline void FujiDecompressor::fuji_zerobits(BitPumpMSB* pump,
+ int* count) const {
uchar8 zero = 0;
*count = 0;
@@ -265,12 +267,10 @@ FujiDecompressor::bitDiff(int value1, int value2) const {
}
template <typename T1, typename T2>
-int FujiDecompressor::fuji_decode_sample(T1&& func_0, T2&& func_1,
- fuji_compressed_block* info,
- BitPumpMSB* pump, ushort16* line_buf,
- int* pos, int_pair* grads) const {
+void FujiDecompressor::fuji_decode_sample(
+ T1&& func_0, T2&& func_1, fuji_compressed_block* info, BitPumpMSB* pump,
+ ushort16* line_buf, int* pos, std::array<int_pair, 41>* grads) const {
int interp_val = 0;
- int errcnt = 0;
int sample = 0;
int code = 0;
@@ -284,7 +284,7 @@ int FujiDecompressor::fuji_decode_sample(T1&& func_0, T2&& func_1,
fuji_zerobits(pump, &sample);
if (sample < common_info.max_bits - common_info.raw_bits - 1) {
- int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2);
+ int decBits = bitDiff((*grads)[gradient].value1, (*grads)[gradient].value2);
code = pump->getBits(decBits);
code += sample << decBits;
} else {
@@ -293,7 +293,7 @@ int FujiDecompressor::fuji_decode_sample(T1&& func_0, T2&& func_1,
}
if (code < 0 || code >= common_info.total_values) {
- errcnt++;
+ ThrowRDE("fuji_decode_sample");
}
if (code & 1) {
@@ -302,14 +302,14 @@ int FujiDecompressor::fuji_decode_sample(T1&& func_0, T2&& func_1,
code /= 2;
}
- grads[gradient].value1 += std::abs(code);
+ (*grads)[gradient].value1 += std::abs(code);
- if (grads[gradient].value2 == common_info.min_value) {
- grads[gradient].value1 >>= 1;
- grads[gradient].value2 >>= 1;
+ if ((*grads)[gradient].value2 == common_info.min_value) {
+ (*grads)[gradient].value1 >>= 1;
+ (*grads)[gradient].value2 >>= 1;
}
- grads[gradient].value2++;
+ (*grads)[gradient].value2++;
interp_val = func_1(grad, interp_val, code);
@@ -326,19 +326,16 @@ int FujiDecompressor::fuji_decode_sample(T1&& func_0, T2&& func_1,
}
*pos += 2;
-
- return errcnt;
}
#define fuji_quant_gradient(v1, v2) \
(9 * ci.q_table[ci.q_point[4] + (v1)] + ci.q_table[ci.q_point[4] + (v2)])
-int FujiDecompressor::fuji_decode_sample_even(fuji_compressed_block* info,
- BitPumpMSB* pump,
- ushort16* line_buf, int* pos,
- int_pair* grads) const {
+void FujiDecompressor::fuji_decode_sample_even(
+ fuji_compressed_block* info, BitPumpMSB* pump, ushort16* line_buf, int* pos,
+ std::array<int_pair, 41>* grads) const {
const auto& ci = common_info;
- return fuji_decode_sample(
+ fuji_decode_sample(
[&ci](const ushort16* line_buf_cur, int* interp_val, int* grad,
int* gradient) {
int Rb = line_buf_cur[-2 - ci.line_width];
@@ -376,12 +373,11 @@ int FujiDecompressor::fuji_decode_sample_even(fuji_compressed_block* info,
info, pump, line_buf, pos, grads);
}
-int FujiDecompressor::fuji_decode_sample_odd(fuji_compressed_block* info,
- BitPumpMSB* pump,
- ushort16* line_buf, int* pos,
- int_pair* grads) const {
+void FujiDecompressor::fuji_decode_sample_odd(
+ fuji_compressed_block* info, BitPumpMSB* pump, ushort16* line_buf, int* pos,
+ std::array<int_pair, 41>* grads) const {
const auto& ci = common_info;
- return fuji_decode_sample(
+ fuji_decode_sample(
[&ci](const ushort16* line_buf_cur, int* interp_val, int* grad,
int* gradient) {
int Ra = line_buf_cur[-1];
@@ -436,26 +432,26 @@ void FujiDecompressor::fuji_decode_interpolation_even(int line_width,
*pos += 2;
}
-void FujiDecompressor::fuji_extend_generic(ushort16* linebuf[_ltotal],
- int line_width, int start,
- int end) const {
+void FujiDecompressor::fuji_extend_generic(
+ std::array<ushort16*, _ltotal> linebuf, int line_width, int start,
+ int end) const {
for (int i = start; i <= end; i++) {
linebuf[i][0] = linebuf[i - 1][1];
linebuf[i][line_width + 1] = linebuf[i - 1][line_width];
}
}
-void FujiDecompressor::fuji_extend_red(ushort16* linebuf[_ltotal],
+void FujiDecompressor::fuji_extend_red(std::array<ushort16*, _ltotal> linebuf,
int line_width) const {
fuji_extend_generic(linebuf, line_width, _R2, _R4);
}
-void FujiDecompressor::fuji_extend_green(ushort16* linebuf[_ltotal],
+void FujiDecompressor::fuji_extend_green(std::array<ushort16*, _ltotal> linebuf,
int line_width) const {
fuji_extend_generic(linebuf, line_width, _G2, _G7);
}
-void FujiDecompressor::fuji_extend_blue(ushort16* linebuf[_ltotal],
+void FujiDecompressor::fuji_extend_blue(std::array<ushort16*, _ltotal> linebuf,
int line_width) const {
fuji_extend_generic(linebuf, line_width, _B2, _B4);
}
@@ -477,8 +473,6 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
ColorPos g;
ColorPos b;
- int errcnt = 0;
-
const int line_width = common_info.line_width;
// FIXME: GCC5 sucks.
@@ -492,10 +486,10 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
even_func(c0, c1, grad, c0_pos, c1_pos);
if (g.even > 8) {
- errcnt += fuji_decode_sample_odd(info, pump, info->linebuf[c0] + 1,
- &c0_pos.odd, info->grad_odd[grad]);
- errcnt += fuji_decode_sample_odd(info, pump, info->linebuf[c1] + 1,
- &c1_pos.odd, info->grad_odd[grad]);
+ fuji_decode_sample_odd(info, pump, info->linebuf[c0] + 1, &c0_pos.odd,
+ &(info->grad_odd[grad]));
+ fuji_decode_sample_odd(info, pump, info->linebuf[c1] + 1, &c1_pos.odd,
+ &(info->grad_odd[grad]));
}
}
};
@@ -505,8 +499,8 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
ColorPos& c1_pos) {
fuji_decode_interpolation_even(line_width, info->linebuf[c0] + 1,
&c0_pos.even);
- errcnt += fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
- &c1_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1, &c1_pos.even,
+ &(info->grad_even[grad]));
},
_R2, _G2, 0, r, g);
@@ -518,8 +512,8 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
pass(
[&](_xt_lines c0, _xt_lines c1, int grad, ColorPos& c0_pos,
ColorPos& c1_pos) {
- errcnt += fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
- &c0_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1, &c0_pos.even,
+ &(info->grad_even[grad]));
fuji_decode_interpolation_even(line_width, info->linebuf[c1] + 1,
&c1_pos.even);
},
@@ -535,9 +529,8 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
[&](_xt_lines c0, _xt_lines c1, int grad, ColorPos& c0_pos,
ColorPos& c1_pos) {
if (c0_pos.even & 3) {
- errcnt +=
- fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
- &c0_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
+ &c0_pos.even, &(info->grad_even[grad]));
} else {
fuji_decode_interpolation_even(line_width, info->linebuf[c0] + 1,
&c0_pos.even);
@@ -557,16 +550,15 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
pass(
[&](_xt_lines c0, _xt_lines c1, int grad, ColorPos& c0_pos,
ColorPos& c1_pos) {
- errcnt += fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
- &c0_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1, &c0_pos.even,
+ &(info->grad_even[grad]));
if ((c1_pos.even & 3) == 2) {
fuji_decode_interpolation_even(line_width, info->linebuf[c1] + 1,
&c1_pos.even);
} else {
- errcnt +=
- fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
- &c1_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
+ &c1_pos.even, &(info->grad_even[grad]));
}
},
_G5, _B3, 0, g, b);
@@ -584,13 +576,12 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
fuji_decode_interpolation_even(line_width, info->linebuf[c0] + 1,
&c0_pos.even);
} else {
- errcnt +=
- fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
- &c0_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
+ &c0_pos.even, &(info->grad_even[grad]));
}
- errcnt += fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
- &c1_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1, &c1_pos.even,
+ &(info->grad_even[grad]));
},
_R4, _G6, 1, r, g);
@@ -607,9 +598,8 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
&c0_pos.even);
if (c1_pos.even & 3) {
- errcnt +=
- fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
- &c1_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
+ &c1_pos.even, &(info->grad_even[grad]));
} else {
fuji_decode_interpolation_even(line_width, info->linebuf[c1] + 1,
&c1_pos.even);
@@ -619,9 +609,6 @@ void FujiDecompressor::xtrans_decode_block(fuji_compressed_block* info,
fuji_extend_green(info->linebuf, line_width);
fuji_extend_blue(info->linebuf, line_width);
-
- if (errcnt)
- ThrowRDE("xtrans_decode_block");
}
void FujiDecompressor::fuji_bayer_decode_block(fuji_compressed_block* info,
@@ -641,25 +628,23 @@ void FujiDecompressor::fuji_bayer_decode_block(fuji_compressed_block* info,
ColorPos g;
ColorPos b;
- int errcnt = 0;
-
const int line_width = common_info.line_width;
auto pass = [&](_xt_lines c0, _xt_lines c1, int grad, ColorPos& c0_pos,
ColorPos& c1_pos) {
while (g.even < line_width || g.odd < line_width) {
if (g.even < line_width) {
- errcnt += fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1,
- &c0_pos.even, info->grad_even[grad]);
- errcnt += fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1,
- &c1_pos.even, info->grad_even[grad]);
+ fuji_decode_sample_even(info, pump, info->linebuf[c0] + 1, &c0_pos.even,
+ &(info->grad_even[grad]));
+ fuji_decode_sample_even(info, pump, info->linebuf[c1] + 1, &c1_pos.even,
+ &(info->grad_even[grad]));
}
if (g.even > 8) {
- errcnt += fuji_decode_sample_odd(info, pump, info->linebuf[c0] + 1,
- &c0_pos.odd, info->grad_odd[grad]);
- errcnt += fuji_decode_sample_odd(info, pump, info->linebuf[c1] + 1,
- &c1_pos.odd, info->grad_odd[grad]);
+ fuji_decode_sample_odd(info, pump, info->linebuf[c0] + 1, &c0_pos.odd,
+ &(info->grad_odd[grad]));
+ fuji_decode_sample_odd(info, pump, info->linebuf[c1] + 1, &c1_pos.odd,
+ &(info->grad_odd[grad]));
}
}
};
@@ -703,9 +688,6 @@ void FujiDecompressor::fuji_bayer_decode_block(fuji_compressed_block* info,
b.reset();
pass_GB(_G7, _B4, 2);
-
- if (errcnt)
- ThrowRDE("fuji decode bayer block");
}
void FujiDecompressor::fuji_decode_strip(
@@ -719,9 +701,9 @@ void FujiDecompressor::fuji_decode_strip(
int b;
};
- const i_pair mtable[6] = {{_R0, _R3}, {_R1, _R4}, {_G0, _G6},
- {_G1, _G7}, {_B0, _B3}, {_B1, _B4}};
- const i_pair ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}};
+ const std::array<i_pair, 6> mtable = {
+ {{_R0, _R3}, {_R1, _R4}, {_G0, _G6}, {_G1, _G7}, {_B0, _B3}, {_B1, _B4}}};
+ const std::array<i_pair, 3> ztable = {{{_R2, 3}, {_G2, 6}, {_B2, 3}}};
for (int cur_line = 0; cur_line < strip.height(); cur_line++) {
if (header.raw_type == 16) {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.h
index 1955e9036..f4a0d9f27 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/FujiDecompressor.h
@@ -26,9 +26,9 @@
#include "io/BitPumpMSB.h" // for BitPumpMSB
#include "io/ByteStream.h" // for ByteStream
#include "metadata/ColorFilterArray.h" // for CFAColor
-#include <algorithm> // for move
#include <array> // for array
#include <cassert> // for assert
+#include <utility> // for move
#include <vector> // for vector
namespace rawspeed {
@@ -115,7 +115,7 @@ protected:
explicit fuji_compressed_params(const FujiDecompressor& d);
std::vector<char> q_table; /* quantization table */
- int q_point[5]; /* quantization points */
+ std::array<int, 5> q_point; /* quantization points */
int max_bits;
int min_value;
int raw_bits;
@@ -158,10 +158,12 @@ protected:
void reset(const fuji_compressed_params* params);
- int_pair grad_even[3][41]; // tables of gradients
- int_pair grad_odd[3][41];
+ // tables of gradients
+ std::array<std::array<int_pair, 41>, 3> grad_even;
+ std::array<std::array<int_pair, 41>, 3> grad_odd;
+
std::vector<ushort16> linealloc;
- ushort16* linebuf[_ltotal];
+ std::array<ushort16*, _ltotal> linebuf;
};
private:
@@ -183,27 +185,30 @@ private:
void copy_line_to_bayer(fuji_compressed_block* info, const FujiStrip& strip,
int cur_line) const;
- void fuji_zerobits(BitPumpMSB* pump, int* count) const;
+ inline void fuji_zerobits(BitPumpMSB* pump, int* count) const;
int bitDiff(int value1, int value2) const;
template <typename T1, typename T2>
- int fuji_decode_sample(T1&& func_0, T2&& func_1, fuji_compressed_block* info,
- BitPumpMSB* pump, ushort16* line_buf, int* pos,
- int_pair* grads) const;
- int fuji_decode_sample_even(fuji_compressed_block* info, BitPumpMSB* pump,
+ void fuji_decode_sample(T1&& func_0, T2&& func_1, fuji_compressed_block* info,
+ BitPumpMSB* pump, ushort16* line_buf, int* pos,
+ std::array<int_pair, 41>* grads) const;
+ void fuji_decode_sample_even(fuji_compressed_block* info, BitPumpMSB* pump,
+ ushort16* line_buf, int* pos,
+ std::array<int_pair, 41>* grads) const;
+ void fuji_decode_sample_odd(fuji_compressed_block* info, BitPumpMSB* pump,
ushort16* line_buf, int* pos,
- int_pair* grads) const;
- int fuji_decode_sample_odd(fuji_compressed_block* info, BitPumpMSB* pump,
- ushort16* line_buf, int* pos,
- int_pair* grads) const;
+ std::array<int_pair, 41>* grads) const;
void fuji_decode_interpolation_even(int line_width, ushort16* line_buf,
int* pos) const;
- void fuji_extend_generic(ushort16* linebuf[_ltotal], int line_width,
- int start, int end) const;
- void fuji_extend_red(ushort16* linebuf[_ltotal], int line_width) const;
- void fuji_extend_green(ushort16* linebuf[_ltotal], int line_width) const;
- void fuji_extend_blue(ushort16* linebuf[_ltotal], int line_width) const;
+ void fuji_extend_generic(std::array<ushort16*, _ltotal> linebuf,
+ int line_width, int start, int end) const;
+ void fuji_extend_red(std::array<ushort16*, _ltotal> linebuf,
+ int line_width) const;
+ void fuji_extend_green(std::array<ushort16*, _ltotal> linebuf,
+ int line_width) const;
+ void fuji_extend_blue(std::array<ushort16*, _ltotal> linebuf,
+ int line_width) const;
void xtrans_decode_block(fuji_compressed_block* info,
BitPumpMSB* pump, int cur_line) const;
void fuji_bayer_decode_block(fuji_compressed_block* info,
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.cpp
index 11a74cf2e..ff0e345cf 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.cpp
@@ -41,7 +41,7 @@ HasselbladDecompressor::HasselbladDecompressor(const ByteStream& bs,
// FIXME: could be wrong. max "active pixels" - "100 MP"
if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 ||
- mRaw->dim.x > 11600 || mRaw->dim.y > 8700) {
+ mRaw->dim.x > 12000 || mRaw->dim.y > 8816) {
ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x,
mRaw->dim.y);
}
@@ -82,8 +82,10 @@ void HasselbladDecompressor::decodeScan() {
int len2 = ht[0]->decodeLength(bitStream);
p1 += getBits(&bitStream, len1);
p2 += getBits(&bitStream, len2);
- dest[x] = p1;
- dest[x+1] = p2;
+ // NOTE: this is rather unusual and weird, but appears to be correct.
+ // clampBits(p, 16) results in completely garbled images.
+ dest[x] = ushort16(p1);
+ dest[x + 1] = ushort16(p2);
}
}
input.skipBytes(bitStream.getBufferPosition());
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.h
index 03535d3cb..47ad90945 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HasselbladDecompressor.h
@@ -23,11 +23,10 @@
#include "decompressors/AbstractLJpegDecompressor.h" // for AbstractLJpegDe...
#include "io/BitPumpMSB32.h" // for BitPumpMSB32
-#include "io/Buffer.h" // for Buffer, Buffer:...
-#include "io/ByteStream.h" // for ByteStream
namespace rawspeed {
+class ByteStream;
class RawImage;
class HasselbladDecompressor final : public AbstractLJpegDecompressor
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTable.h b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTable.h
index 260df3814..6f54bcac1 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTable.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTable.h
@@ -1,8 +1,7 @@
/*
RawSpeed - RAW file decoder.
- Copyright (C) 2017 Axel Waggershauser
- Copyright (C) 2017 Roman Lebedev
+ 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
@@ -21,346 +20,20 @@
#pragma once
-#include "common/Common.h" // for ushort16, uchar8, int32
-#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "io/Buffer.h" // for Buffer
-#include <algorithm> // for copy
-#include <cassert> // for assert
-#include <cstddef> // for size_t
-#include <iterator> // for distance
-#include <numeric> // for accumulate
-#include <vector> // for vector, allocator, operator==
+// IWYU pragma: begin_exports
-/*
-* The following code is inspired by the IJG JPEG library.
-*
-* Copyright (C) 1991, 1992, Thomas G. Lane.
-* Part of the Independent JPEG Group's software.
-* See the file Copyright for more details.
-*
-* Copyright (c) 1993 Brian C. Smith, The Regents of the University
-* of California
-* All rights reserved.
-*
-* Copyright (c) 1994 Kongji Huang and Brian C. Smith.
-* Cornell University
-* All rights reserved.
-*
-* Permission to use, copy, modify, and distribute this software and its
-* documentation for any purpose, without fee, and without written agreement is
-* hereby granted, provided that the above copyright notice and the following
-* two paragraphs appear in all copies of this software.
-*
-* IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
-* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
-* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
-* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
-* ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
-* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-*/
-
-namespace rawspeed {
-
-class HuffmanTable final {
- // private fields calculated from codesPerBits and codeValues
- // they are index '1' based, so we can directly lookup the value
- // for code length l without decrementing
- std::vector<ushort16> maxCodeOL; // index is length of code
- std::vector<ushort16> codeOffsetOL; // index is length of code
-
- // The code can be compiled with two different decode lookup table layouts.
- // The idea is that different CPU architectures may perform better with
- // one or the other, depending on the relative performance of their arithmetic
- // core vs their memory access. For an Intel Core i7, the big table is better.
-#if 1
- // lookup table containing 3 fields: payload:16|flag:8|len:8
- // The payload may be the fully decoded diff or the length of the diff.
- // The len field contains the number of bits, this lookup consumed.
- // A lookup value of 0 means the code was too big to fit into the table.
- // The optimal LookupDepth is also likely to depend on the CPU architecture.
- static constexpr unsigned PayloadShift = 16;
- static constexpr unsigned FlagMask = 0x100;
- static constexpr unsigned LenMask = 0xff;
- static constexpr unsigned LookupDepth = 11;
- std::vector<int32> decodeLookup;
-#else
- // lookup table containing 2 fields: payload:4|len:4
- // the payload is the length of the diff, len is the length of the code
- static constexpr unsigned LookupDepth = 15;
- static constexpr unsigned PayloadShift = 4;
- static constexpr unsigned FlagMask = 0;
- static constexpr unsigned LenMask = 0x0f;
- std::vector<uchar8> decodeLookup;
-#endif
-
- bool fullDecode = true;
- bool fixDNGBug16 = false;
-
- inline size_t __attribute__((pure)) maxCodePlusDiffLength() const {
- return nCodesPerLength.size() - 1 +
- *(std::max_element(codeValues.cbegin(), codeValues.cend()));
- }
-
- // These two fields directly represent the contents of a JPEG DHT field
-
- // 1. The number of codes there are per bit length, this is index 1 based.
- // (there are always 0 codes of length 0)
- std::vector<unsigned int> nCodesPerLength; // index is length of code
- inline unsigned int __attribute__((pure)) maxCodesCount() const {
- return std::accumulate(nCodesPerLength.begin(), nCodesPerLength.end(), 0U);
- }
-
- // 2. This is the actual huffman encoded data, i.e. the 'alphabet'. Each value
- // is the number of bits following the code that encode the difference to the
- // last pixel. Valid values are in the range 0..16.
- // signExtended() is used to decode the difference bits to a signed int.
- std::vector<uchar8> codeValues; // index is just sequential number
-
-public:
- bool operator==(const HuffmanTable& other) const {
- return nCodesPerLength == other.nCodesPerLength
- && codeValues == other.codeValues;
- }
-
- uint32 setNCodesPerLength(const Buffer& data) {
- assert(data.getSize() == 16);
-
- nCodesPerLength.resize(17, 0);
- std::copy(data.begin(), data.end(), &nCodesPerLength[1]);
- assert(nCodesPerLength[0] == 0);
-
- // trim empty entries from the codes per length table on the right
- while (!nCodesPerLength.empty() && nCodesPerLength.back() == 0)
- nCodesPerLength.pop_back();
-
- if (nCodesPerLength.empty())
- ThrowRDE("Codes-per-length table is empty");
-
- assert(nCodesPerLength.back() > 0);
-
- const auto count = maxCodesCount();
- assert(count > 0);
-
- if (count > 162)
- ThrowRDE("Too big code-values table");
-
- for (auto codeLen = 1U; codeLen < nCodesPerLength.size(); codeLen++) {
- // we have codeLen bits. make sure that that code count can actually fit
- const auto nCodes = nCodesPerLength[codeLen];
- if (nCodes > ((1U << codeLen) - 1U)) {
- ThrowRDE("Corrupt Huffman. Can not have %u codes in %u-bit len", nCodes,
- codeLen);
- }
- }
-
- return count;
- }
-
- void setCodeValues(const Buffer& data) {
- // spec says max 16 but Hasselblad ignores that -> allow 17
- // Canon's old CRW really ignores this ...
- assert(data.getSize() <= 162);
- assert(data.getSize() == maxCodesCount());
-
- codeValues.clear();
- codeValues.reserve(maxCodesCount());
- std::copy(data.begin(), data.end(), std::back_inserter(codeValues));
- assert(codeValues.size() == maxCodesCount());
-
- for (const auto cValue : codeValues) {
- if (cValue > 16)
- ThrowRDE("Corrupt Huffman. Code value %u is bigger than 16", cValue);
- }
- }
-
- void setup(bool fullDecode_, bool fixDNGBug16_) {
- this->fullDecode = fullDecode_;
- this->fixDNGBug16 = fixDNGBug16_;
-
- // store the code lengths in bits, valid values are 0..16
- std::vector<uchar8> code_len; // index is just sequential number
- // store the codes themselves (bit patterns found inside the stream)
- std::vector<ushort16> codes; // index is just sequential number
-
- assert(!nCodesPerLength.empty());
- assert(maxCodesCount() > 0);
+#include "decompressors/HuffmanTableLUT.h" // for HuffmanTableLUT
+// #include "decompressors/HuffmanTableLookup.h" // for HuffmanTableLookup
+// #include "decompressors/HuffmanTableTree.h" // for HuffmanTableTree
+// #include "decompressors/HuffmanTableVector.h" // for HuffmanTableVector
- unsigned int maxCodeLength = nCodesPerLength.size() - 1U;
- assert(codeValues.size() == maxCodesCount());
+// IWYU pragma: end_exports
- assert(maxCodePlusDiffLength() <= 32U);
-
- // reserve all the memory. avoids lots of small allocs
- code_len.reserve(maxCodesCount());
- codes.reserve(maxCodesCount());
-
- // Figure C.1: make table of Huffman code length for each symbol
- // Figure C.2: generate the codes themselves
- uint32 code = 0;
- for (unsigned int l = 1; l <= maxCodeLength; ++l) {
- assert(nCodesPerLength[l] <= ((1U << l) - 1U));
-
- for (unsigned int i = 0; i < nCodesPerLength[l]; ++i) {
- if (code > 0xffff) {
- ThrowRDE("Corrupt Huffman: code value overflow on len = %u, %u-th "
- "code out of %u\n",
- l, i, nCodesPerLength[l]);
- }
-
- code_len.push_back(l);
- codes.push_back(code);
- code++;
- }
- code <<= 1;
- }
-
- assert(code_len.size() == maxCodesCount());
- assert(codes.size() == maxCodesCount());
-
- // Figure F.15: generate decoding tables
- codeOffsetOL.resize(maxCodeLength + 1UL, 0xffff);
- maxCodeOL.resize(maxCodeLength + 1UL);
- int code_index = 0;
- for (unsigned int l = 1U; l <= maxCodeLength; l++) {
- if (nCodesPerLength[l]) {
- codeOffsetOL[l] = codes[code_index] - code_index;
- code_index += nCodesPerLength[l];
- maxCodeOL[l] = codes[code_index - 1];
- }
- }
-
- // Generate lookup table for fast decoding lookup.
- // See definition of decodeLookup above
- decodeLookup.resize(1 << LookupDepth);
- for (size_t i = 0; i < codes.size(); i++) {
- uchar8 code_l = code_len[i];
- if (code_l > static_cast<int>(LookupDepth))
- break;
-
- ushort16 ll = codes[i] << (LookupDepth - code_l);
- ushort16 ul = ll | ((1 << (LookupDepth - code_l)) - 1);
- ushort16 diff_l = codeValues[i];
- for (ushort16 c = ll; c <= ul; c++) {
- if (!(c < decodeLookup.size()))
- ThrowRDE("Corrupt Huffman");
-
- if (!FlagMask || !fullDecode || diff_l + code_l > LookupDepth) {
- // lookup bit depth is too small to fit both the encoded length
- // and the final difference value.
- // -> store only the length and do a normal sign extension later
- decodeLookup[c] = diff_l << PayloadShift | code_l;
- } else {
- // diff_l + code_l <= lookupDepth
- // The table bit depth is large enough to store both.
- decodeLookup[c] = (code_l + diff_l) | FlagMask;
-
- if (diff_l) {
- uint32 diff = (c >> (LookupDepth - code_l - diff_l)) & ((1 << diff_l) - 1);
- decodeLookup[c] |= static_cast<uint32>(signExtended(diff, diff_l))
- << PayloadShift;
- }
- }
- }
- }
- }
-
- // WARNING: the caller should check that len != 0 before calling the function
- inline static int __attribute__((const))
- signExtended(uint32 diff, uint32 len) {
- int32 ret = diff;
-#if 0
-#define _X(x) (1<<x)-1
- constexpr static int offset[16] = {
- 0, _X(1), _X(2), _X(3), _X(4), _X(5), _X(6), _X(7),
- _X(8), _X(9), _X(10), _X(11), _X(12), _X(13), _X(14), _X(15)};
-#undef _X
- if ((diff & (1 << (len - 1))) == 0)
- ret -= offset[len];
-#else
- if ((diff & (1 << (len - 1))) == 0)
- ret -= (1 << len) - 1;
-#endif
- return ret;
- }
-
- template<typename BIT_STREAM> inline int decodeLength(BIT_STREAM& bs) const {
- assert(!fullDecode);
- return decode<BIT_STREAM, false>(bs);
- }
-
- template<typename BIT_STREAM> inline int decodeNext(BIT_STREAM& bs) const {
- assert(fullDecode);
- return decode<BIT_STREAM, true>(bs);
- }
-
- // The bool template paraeter is to enable two versions:
- // one returning only the length of the of diff bits (see Hasselblad),
- // one to return the fully decoded diff.
- // All ifs depending on this bool will be optimized out by the compiler
- template<typename BIT_STREAM, bool FULL_DECODE> inline int decode(BIT_STREAM& bs) const {
- assert(FULL_DECODE == fullDecode);
-
- // 32 is the absolute maximum combined length of code + diff
- // assertion maxCodePlusDiffLength() <= 32U is already checked in setup()
- bs.fill(32);
-
- // for processors supporting bmi2 instructions, using maxCodePlusDiffLength()
- // might be benifitial
-
- uint32 code = bs.peekBitsNoFill(LookupDepth);
- assert(code < decodeLookup.size());
- int val = decodeLookup[code];
- int len = val & LenMask;
- assert(len >= 0);
- assert(len <= 16);
-
- // if the code is invalid (bitstream corrupted) len will be 0
- bs.skipBitsNoFill(len);
- if (FULL_DECODE && val & FlagMask) {
- // if the flag bit is set, the payload is the already sign extended difference
- return val >> PayloadShift;
- }
-
- if (len) {
- // if the flag bit is not set but len != 0, the payload is the number of bits to sign extend and return
- const int l_diff = val >> PayloadShift;
- assert((FULL_DECODE && (len + l_diff <= 32)) || !FULL_DECODE);
- return FULL_DECODE ? signExtended(bs.getBitsNoFill(l_diff), l_diff) : l_diff;
- }
-
- uint32 code_l = LookupDepth;
- bs.skipBitsNoFill(code_l);
- while (code_l < maxCodeOL.size() && code > maxCodeOL[code_l]) {
- uint32 temp = bs.getBitsNoFill(1);
- code = (code << 1) | temp;
- code_l++;
- }
-
- if (code_l >= maxCodeOL.size() || code > maxCodeOL[code_l])
- ThrowRDE("bad Huffman code: %u (len: %u)", code, code_l);
-
- if (code < codeOffsetOL[code_l])
- ThrowRDE("likely corrupt Huffman code: %u (len: %u)", code, code_l);
-
- int diff_l = codeValues[code - codeOffsetOL[code_l]];
-
- if (!FULL_DECODE)
- return diff_l;
-
- if (diff_l == 16) {
- if (fixDNGBug16)
- bs.skipBits(16);
- return -32768;
- }
+namespace rawspeed {
- assert(FULL_DECODE);
- assert((diff_l && (len + code_l + diff_l <= 32)) || !diff_l);
- return diff_l ? signExtended(bs.getBitsNoFill(diff_l), diff_l) : 0;
- }
-};
+using HuffmanTable = HuffmanTableLUT;
+// using HuffmanTable = HuffmanTableLookup;
+// using HuffmanTable = HuffmanTableTree;
+// using HuffmanTable = HuffmanTableVector;
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLUT.h b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLUT.h
new file mode 100644
index 000000000..45c7c31c5
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLUT.h
@@ -0,0 +1,257 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017 Axel Waggershauser
+ Copyright (C) 2017-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
+*/
+
+#pragma once
+
+#include "common/Common.h" // for uint32, ushort16, int32
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/AbstractHuffmanTable.h" // for AbstractHuffmanTable
+#include "io/BitStream.h" // for BitStreamTraits
+#include <cassert> // for assert
+#include <cstddef> // for size_t
+#include <memory> // for allocator_traits<>::...
+#include <vector> // for vector
+
+/*
+* The following code is inspired by the IJG JPEG library.
+*
+* Copyright (C) 1991, 1992, Thomas G. Lane.
+* Part of the Independent JPEG Group's software.
+* See the file Copyright for more details.
+*
+* Copyright (c) 1993 Brian C. Smith, The Regents of the University
+* of California
+* All rights reserved.
+*
+* Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+* Cornell University
+* All rights reserved.
+*
+* Permission to use, copy, modify, and distribute this software and its
+* documentation for any purpose, without fee, and without written agreement is
+* hereby granted, provided that the above copyright notice and the following
+* two paragraphs appear in all copies of this software.
+*
+* IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+* ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+namespace rawspeed {
+
+class HuffmanTableLUT final : public AbstractHuffmanTable {
+ // private fields calculated from codesPerBits and codeValues
+ // they are index '1' based, so we can directly lookup the value
+ // for code length l without decrementing
+ std::vector<uint32> maxCodeOL; // index is length of code
+ std::vector<ushort16> codeOffsetOL; // index is length of code
+
+ // The code can be compiled with two different decode lookup table layouts.
+ // The idea is that different CPU architectures may perform better with
+ // one or the other, depending on the relative performance of their arithmetic
+ // core vs their memory access. For an Intel Core i7, the big table is better.
+#if 1
+ // lookup table containing 3 fields: payload:16|flag:8|len:8
+ // The payload may be the fully decoded diff or the length of the diff.
+ // The len field contains the number of bits, this lookup consumed.
+ // A lookup value of 0 means the code was too big to fit into the table.
+ // The optimal LookupDepth is also likely to depend on the CPU architecture.
+ static constexpr unsigned PayloadShift = 16;
+ static constexpr unsigned FlagMask = 0x100;
+ static constexpr unsigned LenMask = 0xff;
+ static constexpr unsigned LookupDepth = 11;
+ std::vector<int32> decodeLookup;
+#else
+ // lookup table containing 2 fields: payload:4|len:4
+ // the payload is the length of the diff, len is the length of the code
+ static constexpr unsigned LookupDepth = 15;
+ static constexpr unsigned PayloadShift = 4;
+ static constexpr unsigned FlagMask = 0;
+ static constexpr unsigned LenMask = 0x0f;
+ std::vector<uchar8> decodeLookup;
+#endif
+
+ bool fullDecode = true;
+ bool fixDNGBug16 = false;
+
+public:
+ void setup(bool fullDecode_, bool fixDNGBug16_) {
+ this->fullDecode = fullDecode_;
+ this->fixDNGBug16 = fixDNGBug16_;
+
+ assert(!nCodesPerLength.empty());
+ assert(maxCodesCount() > 0);
+
+ unsigned int maxCodeLength = nCodesPerLength.size() - 1U;
+ assert(codeValues.size() == maxCodesCount());
+
+ assert(maxCodePlusDiffLength() <= 32U);
+
+ // Figure C.1: make table of Huffman code length for each symbol
+ // Figure C.2: generate the codes themselves
+ const auto symbols = generateCodeSymbols();
+ assert(symbols.size() == maxCodesCount());
+
+ // Figure F.15: generate decoding tables
+ codeOffsetOL.resize(maxCodeLength + 1UL, 0xFFFF);
+ maxCodeOL.resize(maxCodeLength + 1UL, 0xFFFFFFFF);
+ int code_index = 0;
+ for (unsigned int l = 1U; l <= maxCodeLength; l++) {
+ if (nCodesPerLength[l]) {
+ codeOffsetOL[l] = symbols[code_index].code - code_index;
+ code_index += nCodesPerLength[l];
+ maxCodeOL[l] = symbols[code_index - 1].code;
+ }
+ }
+
+ // Generate lookup table for fast decoding lookup.
+ // See definition of decodeLookup above
+ decodeLookup.resize(1 << LookupDepth);
+ for (size_t i = 0; i < symbols.size(); i++) {
+ uchar8 code_l = symbols[i].code_len;
+ if (code_l > static_cast<int>(LookupDepth))
+ break;
+
+ ushort16 ll = symbols[i].code << (LookupDepth - code_l);
+ ushort16 ul = ll | ((1 << (LookupDepth - code_l)) - 1);
+ ushort16 diff_l = codeValues[i];
+ for (ushort16 c = ll; c <= ul; c++) {
+ if (!(c < decodeLookup.size()))
+ ThrowRDE("Corrupt Huffman");
+
+ if (!FlagMask || !fullDecode || diff_l + code_l > LookupDepth) {
+ // lookup bit depth is too small to fit both the encoded length
+ // and the final difference value.
+ // -> store only the length and do a normal sign extension later
+ decodeLookup[c] = diff_l << PayloadShift | code_l;
+ } else {
+ // diff_l + code_l <= lookupDepth
+ // The table bit depth is large enough to store both.
+ decodeLookup[c] = (code_l + diff_l) | FlagMask;
+
+ if (diff_l) {
+ uint32 diff = (c >> (LookupDepth - code_l - diff_l)) & ((1 << diff_l) - 1);
+ decodeLookup[c] |= static_cast<int32>(
+ static_cast<uint32>(signExtended(diff, diff_l))
+ << PayloadShift);
+ }
+ }
+ }
+ }
+ }
+
+ template<typename BIT_STREAM> inline int decodeLength(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(!fullDecode);
+ return decode<BIT_STREAM, false>(bs);
+ }
+
+ template<typename BIT_STREAM> inline int decodeNext(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(fullDecode);
+ return decode<BIT_STREAM, true>(bs);
+ }
+
+ // The bool template paraeter is to enable two versions:
+ // one returning only the length of the of diff bits (see Hasselblad),
+ // one to return the fully decoded diff.
+ // All ifs depending on this bool will be optimized out by the compiler
+ template<typename BIT_STREAM, bool FULL_DECODE> inline int decode(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(FULL_DECODE == fullDecode);
+
+ // 32 is the absolute maximum combined length of code + diff
+ // assertion maxCodePlusDiffLength() <= 32U is already checked in setup()
+ bs.fill(32);
+
+ // for processors supporting bmi2 instructions, using maxCodePlusDiffLength()
+ // might be benifitial
+
+ uint32 code = bs.peekBitsNoFill(LookupDepth);
+ assert(code < decodeLookup.size());
+ auto val = static_cast<unsigned>(decodeLookup[code]);
+ int len = val & LenMask;
+ assert(len >= 0);
+ assert(len <= 16);
+
+ // if the code is invalid (bitstream corrupted) len will be 0
+ bs.skipBitsNoFill(len);
+ if (FULL_DECODE && val & FlagMask) {
+ // if the flag bit is set, the payload is the already sign extended difference
+ return static_cast<int>(val) >> PayloadShift;
+ }
+
+ if (len) {
+ // if the flag bit is not set but len != 0, the payload is the number of bits to sign extend and return
+ const int l_diff = static_cast<int>(val) >> PayloadShift;
+ assert((FULL_DECODE && (len + l_diff <= 32)) || !FULL_DECODE);
+ if (FULL_DECODE && l_diff == 16) {
+ if (fixDNGBug16)
+ bs.skipBits(16);
+ return -32768;
+ }
+ return FULL_DECODE ? signExtended(bs.getBitsNoFill(l_diff), l_diff) : l_diff;
+ }
+
+ uint32 code_l = LookupDepth;
+ bs.skipBitsNoFill(code_l);
+ while (code_l < maxCodeOL.size() &&
+ (0xFFFFFFFF == maxCodeOL[code_l] || code > maxCodeOL[code_l])) {
+ uint32 temp = bs.getBitsNoFill(1);
+ code = (code << 1) | temp;
+ code_l++;
+ }
+
+ if (code_l >= maxCodeOL.size() ||
+ (0xFFFFFFFF == maxCodeOL[code_l] || code > maxCodeOL[code_l]))
+ ThrowRDE("bad Huffman code: %u (len: %u)", code, code_l);
+
+ if (code < codeOffsetOL[code_l])
+ ThrowRDE("likely corrupt Huffman code: %u (len: %u)", code, code_l);
+
+ int diff_l = codeValues[code - codeOffsetOL[code_l]];
+
+ if (!FULL_DECODE)
+ return diff_l;
+
+ if (diff_l == 16) {
+ if (fixDNGBug16)
+ bs.skipBits(16);
+ return -32768;
+ }
+
+ assert(FULL_DECODE);
+ assert((diff_l && (len + code_l + diff_l <= 32)) || !diff_l);
+ return diff_l ? signExtended(bs.getBitsNoFill(diff_l), diff_l) : 0;
+ }
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLookup.h b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLookup.h
new file mode 100644
index 000000000..df8408ccf
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableLookup.h
@@ -0,0 +1,171 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017 Axel Waggershauser
+ Copyright (C) 2017-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
+*/
+
+#pragma once
+
+#include "common/Common.h" // for uint32, ushort16
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/AbstractHuffmanTable.h" // for AbstractHuffmanTable
+#include "io/BitStream.h" // for BitStreamTraits
+#include <cassert> // for assert
+#include <memory> // for allocator_traits<>::...
+#include <vector> // for vector
+
+/*
+ * The following code is inspired by the IJG JPEG library.
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+namespace rawspeed {
+
+class HuffmanTableLookup final : public AbstractHuffmanTable {
+ // private fields calculated from codesPerBits and codeValues
+ // they are index '1' based, so we can directly lookup the value
+ // for code length l without decrementing
+ std::vector<uint32> maxCodeOL; // index is length of code
+ std::vector<ushort16> codeOffsetOL; // index is length of code
+
+ bool fullDecode = true;
+ bool fixDNGBug16 = false;
+
+public:
+ void setup(bool fullDecode_, bool fixDNGBug16_) {
+ this->fullDecode = fullDecode_;
+ this->fixDNGBug16 = fixDNGBug16_;
+
+ assert(!nCodesPerLength.empty());
+ assert(maxCodesCount() > 0);
+
+ unsigned int maxCodeLength = nCodesPerLength.size() - 1U;
+ assert(codeValues.size() == maxCodesCount());
+
+ assert(maxCodePlusDiffLength() <= 32U);
+
+ // Figure C.1: make table of Huffman code length for each symbol
+ // Figure C.2: generate the codes themselves
+ const auto symbols = generateCodeSymbols();
+ assert(symbols.size() == maxCodesCount());
+
+ // Figure F.15: generate decoding tables
+ codeOffsetOL.resize(maxCodeLength + 1UL, 0xFFFF);
+ maxCodeOL.resize(maxCodeLength + 1UL, 0xFFFFFFFF);
+ int code_index = 0;
+ for (unsigned int l = 1U; l <= maxCodeLength; l++) {
+ if (nCodesPerLength[l]) {
+ codeOffsetOL[l] = symbols[code_index].code - code_index;
+ code_index += nCodesPerLength[l];
+ maxCodeOL[l] = symbols[code_index - 1].code;
+ }
+ }
+ }
+
+ template <typename BIT_STREAM> inline int decodeLength(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(!fullDecode);
+ return decode<BIT_STREAM, false>(bs);
+ }
+
+ template <typename BIT_STREAM> inline int decodeNext(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(fullDecode);
+ return decode<BIT_STREAM, true>(bs);
+ }
+
+ // The bool template paraeter is to enable two versions:
+ // one returning only the length of the of diff bits (see Hasselblad),
+ // one to return the fully decoded diff.
+ // All ifs depending on this bool will be optimized out by the compiler
+ template <typename BIT_STREAM, bool FULL_DECODE>
+ inline int decode(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(FULL_DECODE == fullDecode);
+
+ // 32 is the absolute maximum combined length of code + diff
+ // assertion maxCodePlusDiffLength() <= 32U is already checked in setup()
+ bs.fill(32);
+
+ // for processors supporting bmi2 instructions, using
+ // maxCodePlusDiffLength() might be benifitial
+
+ uint32 code = 0;
+ uint32 code_l = 0;
+ while (code_l < maxCodeOL.size() &&
+ (0xFFFFFFFF == maxCodeOL[code_l] || code > maxCodeOL[code_l])) {
+ uint32 temp = bs.getBitsNoFill(1);
+ code = (code << 1) | temp;
+ code_l++;
+ }
+
+ if (code_l >= maxCodeOL.size() ||
+ (0xFFFFFFFF == maxCodeOL[code_l] || code > maxCodeOL[code_l]))
+ ThrowRDE("bad Huffman code: %u (len: %u)", code, code_l);
+
+ if (code < codeOffsetOL[code_l])
+ ThrowRDE("likely corrupt Huffman code: %u (len: %u)", code, code_l);
+
+ int diff_l = codeValues[code - codeOffsetOL[code_l]];
+
+ if (!FULL_DECODE)
+ return diff_l;
+
+ if (diff_l == 16) {
+ if (fixDNGBug16)
+ bs.skipBits(16);
+ return -32768;
+ }
+
+ assert(FULL_DECODE);
+ assert((diff_l && (code_l + diff_l <= 32)) || !diff_l);
+ return diff_l ? signExtended(bs.getBitsNoFill(diff_l), diff_l) : 0;
+ }
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableTree.h b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableTree.h
new file mode 100644
index 000000000..0dd0088e4
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableTree.h
@@ -0,0 +1,165 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017 Axel Waggershauser
+ 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
+*/
+
+#pragma once
+
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/AbstractHuffmanTable.h" // for AbstractHuffmanTable...
+#include "decompressors/BinaryHuffmanTree.h" // IWYU pragma: export
+#include "io/BitStream.h" // for BitStreamTraits
+#include <algorithm> // for for_each
+#include <cassert> // for assert
+#include <initializer_list> // for initializer_list
+#include <iterator> // for advance, next
+#include <memory> // for unique_ptr, make_unique
+#include <vector> // for vector, vector<>::co...
+
+namespace rawspeed {
+
+class HuffmanTableTree final : public AbstractHuffmanTable {
+ using ValueType = decltype(codeValues)::value_type;
+
+ BinaryHuffmanTree<ValueType> tree;
+
+ bool fullDecode = true;
+ bool fixDNGBug16 = false;
+
+protected:
+ template <typename BIT_STREAM>
+ inline ValueType getValue(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ CodeSymbol partial;
+
+ const auto* top = &(tree.root->getAsBranch());
+
+ // Read bits until either find the code or detect the uncorrect code
+ for (partial.code = 0, partial.code_len = 1;; ++partial.code_len) {
+ assert(partial.code_len <= 16);
+
+ // Read one more bit
+ const bool bit = bs.getBits(1);
+
+ partial.code <<= 1;
+ partial.code |= bit;
+
+ // What is the last bit, which we have just read?
+
+ // NOTE: The order *IS* important! Left to right, zero to one!
+ const auto& newNode = !bit ? top->zero : top->one;
+
+ if (!newNode) {
+ // Got nothing in this direction.
+ ThrowRDE("bad Huffman code: %u (len: %u)", partial.code,
+ partial.code_len);
+ }
+
+ if (static_cast<decltype(tree)::Node::Type>(*newNode) ==
+ decltype(tree)::Node::Type::Leaf) {
+ // Ok, great, hit a Leaf. This is it.
+ return newNode->getAsLeaf().value;
+ }
+
+ // Else, this is a branch, continue looking.
+ top = &(newNode->getAsBranch());
+ }
+
+ // We have either returned the found symbol, or thrown on uncorrect symbol.
+ __builtin_unreachable();
+ }
+
+public:
+ void setup(bool fullDecode_, bool fixDNGBug16_) {
+ this->fullDecode = fullDecode_;
+ this->fixDNGBug16 = fixDNGBug16_;
+
+ assert(!nCodesPerLength.empty());
+ assert(maxCodesCount() > 0);
+ assert(codeValues.size() == maxCodesCount());
+
+ auto currValue = codeValues.cbegin();
+ for (auto codeLen = 1UL; codeLen < nCodesPerLength.size(); codeLen++) {
+ const auto nCodesForCurrLen = nCodesPerLength[codeLen];
+
+ auto nodes = tree.getAllVacantNodesAtDepth(codeLen);
+ if (nodes.size() < nCodesForCurrLen) {
+ ThrowRDE("Got too many (%u) codes for len %lu, can only have %zu codes",
+ nCodesForCurrLen, codeLen, nodes.size());
+ }
+
+ // Make first nCodesForCurrLen nodes Leafs
+ std::for_each(nodes.cbegin(), std::next(nodes.cbegin(), nCodesForCurrLen),
+ [&currValue](auto* node) {
+ *node =
+ std::make_unique<decltype(tree)::Leaf>(*currValue);
+ std::advance(currValue, 1);
+ });
+ }
+
+ assert(codeValues.cend() == currValue);
+
+ // And get rid of all the branches that do not lead to Leafs.
+ // It is crucial to detect degenerate codes at the earliest.
+ tree.pruneLeaflessBranches();
+ }
+
+ template <typename BIT_STREAM> inline int decodeLength(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(!fullDecode);
+ return decode<BIT_STREAM, false>(bs);
+ }
+
+ template <typename BIT_STREAM> inline int decodeNext(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(fullDecode);
+ return decode<BIT_STREAM, true>(bs);
+ }
+
+ // The bool template paraeter is to enable two versions:
+ // one returning only the length of the of diff bits (see Hasselblad),
+ // one to return the fully decoded diff.
+ // All ifs depending on this bool will be optimized out by the compiler
+ template <typename BIT_STREAM, bool FULL_DECODE>
+ inline int decode(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(FULL_DECODE == fullDecode);
+
+ const auto codeValue = getValue(bs);
+
+ const int diff_l = codeValue;
+
+ if (!FULL_DECODE)
+ return diff_l;
+
+ if (diff_l == 16) {
+ if (fixDNGBug16)
+ bs.skipBits(16);
+ return -32768;
+ }
+
+ return diff_l ? signExtended(bs.getBits(diff_l), diff_l) : 0;
+ }
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableVector.h b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableVector.h
new file mode 100644
index 000000000..3a1c8824a
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/HuffmanTableVector.h
@@ -0,0 +1,155 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2017 Axel Waggershauser
+ 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
+*/
+
+#pragma once
+
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/AbstractHuffmanTable.h" // for AbstractHuffmanTable...
+#include "io/BitStream.h" // for BitStreamTraits
+#include <cassert> // for assert
+#include <utility> // for make_pair, pair
+#include <vector> // for vector
+
+namespace rawspeed {
+
+class HuffmanTableVector final : public AbstractHuffmanTable {
+ std::vector<CodeSymbol> symbols;
+
+ bool fullDecode = true;
+ bool fixDNGBug16 = false;
+
+ // Given this code len, which code id is the minimal?
+ std::vector<unsigned int> extrCodeIdForLen; // index is length of code
+
+protected:
+ template <typename BIT_STREAM>
+ inline std::pair<CodeSymbol, unsigned> getSymbol(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+
+ CodeSymbol partial;
+ unsigned long codeId;
+
+ // Read bits until either find the code or detect the uncorrect code
+ for (partial.code = 0, partial.code_len = 1;; ++partial.code_len) {
+ assert(partial.code_len <= 16);
+
+ // Read one more bit
+ const bool bit = bs.getBits(1);
+
+ partial.code <<= 1;
+ partial.code |= bit;
+
+ // Given global ordering and the code length, we know the code id range.
+ for (codeId = extrCodeIdForLen[partial.code_len];
+ codeId < extrCodeIdForLen[1U + partial.code_len]; codeId++) {
+ const CodeSymbol& symbol = symbols[codeId];
+ if (symbol == partial) // yay, found?
+ return std::make_pair(symbol, codeId);
+ }
+
+ // Ok, but does any symbol have this same prefix?
+ bool haveCommonPrefix = false;
+ for (; codeId < symbols.size(); codeId++) {
+ const CodeSymbol& symbol = symbols[codeId];
+ haveCommonPrefix |= CodeSymbol::HaveCommonPrefix(symbol, partial);
+ if (haveCommonPrefix)
+ break;
+ }
+
+ // If no symbols have this prefix, then the code is invalid.
+ if (!haveCommonPrefix) {
+ ThrowRDE("bad Huffman code: %u (len: %u)", partial.code,
+ partial.code_len);
+ }
+ }
+
+ // We have either returned the found symbol, or thrown on uncorrect symbol.
+ __builtin_unreachable();
+ }
+
+public:
+ void setup(bool fullDecode_, bool fixDNGBug16_) {
+ this->fullDecode = fullDecode_;
+ this->fixDNGBug16 = fixDNGBug16_;
+
+ assert(!nCodesPerLength.empty());
+ assert(maxCodesCount() > 0);
+ assert(codeValues.size() == maxCodesCount());
+
+ // Figure C.1: make table of Huffman code length for each symbol
+ // Figure C.2: generate the codes themselves
+ symbols = generateCodeSymbols();
+ assert(symbols.size() == maxCodesCount());
+
+ extrCodeIdForLen.reserve(1U + nCodesPerLength.size());
+ extrCodeIdForLen.resize(2); // for len 0 and 1, the min code id is always 0
+ for (auto codeLen = 1UL; codeLen < nCodesPerLength.size(); codeLen++) {
+ auto minCodeId = extrCodeIdForLen.back();
+ minCodeId += nCodesPerLength[codeLen];
+ extrCodeIdForLen.emplace_back(minCodeId);
+ }
+ assert(extrCodeIdForLen.size() == 1U + nCodesPerLength.size());
+ }
+
+ template <typename BIT_STREAM> inline int decodeLength(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(!fullDecode);
+ return decode<BIT_STREAM, false>(bs);
+ }
+
+ template <typename BIT_STREAM> inline int decodeNext(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(fullDecode);
+ return decode<BIT_STREAM, true>(bs);
+ }
+
+ // The bool template paraeter is to enable two versions:
+ // one returning only the length of the of diff bits (see Hasselblad),
+ // one to return the fully decoded diff.
+ // All ifs depending on this bool will be optimized out by the compiler
+ template <typename BIT_STREAM, bool FULL_DECODE>
+ inline int decode(BIT_STREAM& bs) const {
+ static_assert(BitStreamTraits<BIT_STREAM>::canUseWithHuffmanTable,
+ "This BitStream specialization is not marked as usable here");
+ assert(FULL_DECODE == fullDecode);
+
+ const auto got = getSymbol(bs);
+ const unsigned codeId = got.second;
+
+ const int diff_l = codeValues[codeId];
+
+ if (!FULL_DECODE)
+ return diff_l;
+
+ if (diff_l == 16) {
+ if (fixDNGBug16)
+ bs.skipBits(16);
+ return -32768;
+ }
+
+ return diff_l ? signExtended(bs.getBits(diff_l), diff_l) : 0;
+ }
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.cpp
index 63d56b50d..13fabb6cb 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.cpp
@@ -96,9 +96,10 @@ static void jpeg_mem_src_int(j_decompress_ptr cinfo,
#endif
[[noreturn]] METHODDEF(void) my_error_throw(j_common_ptr cinfo) {
- char buf[JMSG_LENGTH_MAX] = {0};
- (*cinfo->err->format_message)(cinfo, buf);
- ThrowRDE("JPEG decoder error: %s", buf);
+ std::array<char, JMSG_LENGTH_MAX> buf;
+ buf.fill(0);
+ (*cinfo->err->format_message)(cinfo, buf.data());
+ ThrowRDE("JPEG decoder error: %s", buf.data());
}
struct JpegDecompressor::JpegDecompressStruct : jpeg_decompress_struct {
@@ -130,9 +131,11 @@ void JpegDecompressor::decode(uint32 offX,
ThrowRDE("Component count doesn't match");
int row_stride = dinfo.output_width * dinfo.output_components;
- unique_ptr<uchar8[], decltype(&alignedFree)> complete_buffer(
- alignedMallocArray<uchar8, 16>(dinfo.output_height, row_stride),
- &alignedFree);
+ unique_ptr<uchar8[], // NOLINT
+ decltype(&alignedFree)>
+ complete_buffer(
+ alignedMallocArray<uchar8, 16>(dinfo.output_height, row_stride),
+ &alignedFree);
while (dinfo.output_scanline < dinfo.output_height) {
buffer[0] = static_cast<JSAMPROW>(
&complete_buffer[static_cast<size_t>(dinfo.output_scanline) *
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.h
index ed1ddfd27..114c6ed89 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/JpegDecompressor.h
@@ -27,9 +27,8 @@
#include "common/Common.h" // for uint32
#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
-#include "io/Buffer.h" // for Buffer, Buffer::size_type
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for getHostEndianness
+#include "io/Endianness.h" // for Endianness, Endianne...
#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.cpp
index 81388f8e3..7d19a5603 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.cpp
@@ -20,23 +20,24 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "rawspeedconfig.h"
#include "decompressors/KodakDecompressor.h"
-#include "common/RawImage.h" // for RawImage
-#include "decoders/RawDecoderException.h" // for RawDecoderException (ptr o...
+#include "common/Point.h" // for iPoint2D
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/HuffmanTable.h" // for HuffmanTable
#include "io/ByteStream.h" // for ByteStream
#include <algorithm> // for min
#include <array> // for array
#include <cassert> // for assert
+#include <utility> // for move
namespace rawspeed {
constexpr int KodakDecompressor::segment_size;
KodakDecompressor::KodakDecompressor(const RawImage& img, ByteStream bs,
- bool uncorrectedRawValues_)
- : mRaw(img), input(std::move(bs)),
+ int bps_, bool uncorrectedRawValues_)
+ : mRaw(img), input(std::move(bs)), bps(bps_),
uncorrectedRawValues(uncorrectedRawValues_) {
if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
mRaw->getBpp() != 2)
@@ -47,6 +48,9 @@ KodakDecompressor::KodakDecompressor(const RawImage& img, ByteStream bs,
ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x,
mRaw->dim.y);
+ if (bps != 10 && bps != 12)
+ ThrowRDE("Unexpected bits per sample: %i", bps);
+
// Lower estimate: this decompressor requires *at least* half a byte
// per output pixel
input.check(mRaw->dim.area() / 2ULL);
@@ -83,6 +87,7 @@ KodakDecompressor::decodeSegment(const uint32 bsize) {
}
for (uint32 i = 0; i < bsize; i++) {
uint32 len = blen[i];
+ assert(len < 16);
if (bits < len) {
for (uint32 j = 0; j < 32; j += 8) {
@@ -95,9 +100,8 @@ KodakDecompressor::decodeSegment(const uint32 bsize) {
uint32 diff = static_cast<uint32>(bitbuf) & (0xffff >> (16 - len));
bitbuf >>= len;
bits -= len;
- diff = len != 0 ? HuffmanTable::signExtended(diff, len) : diff;
- out[i] = diff;
+ out[i] = len != 0 ? HuffmanTable::signExtended(diff, len) : int(diff);
}
return out;
@@ -116,15 +120,15 @@ void KodakDecompressor::decompress() {
const segment buf = decodeSegment(len);
- std::array<uint32, 2> pred;
+ std::array<int, 2> pred;
pred.fill(0);
for (uint32 i = 0; i < len; i++) {
pred[i & 1] += buf[i];
- ushort16 value = pred[i & 1];
- if (value > 1023)
- ThrowRDE("Value out of bounds %d", value);
+ int value = pred[i & 1];
+ if (unsigned(value) >= (1U << bps))
+ ThrowRDE("Value out of bounds %d (bps = %i)", value, bps);
if (uncorrectedRawValues)
dest[x + i] = value;
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.h
index 9b89edc12..14bc4f0bf 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/KodakDecompressor.h
@@ -33,15 +33,16 @@ namespace rawspeed {
class KodakDecompressor final : public AbstractDecompressor {
RawImage mRaw;
ByteStream input;
+ int bps;
bool uncorrectedRawValues;
static constexpr int segment_size = 256; // pixels
- using segment = std::array<ushort16, segment_size>;
+ using segment = std::array<short16, segment_size>;
segment decodeSegment(uint32 bsize);
public:
- KodakDecompressor(const RawImage& img, ByteStream bs,
+ KodakDecompressor(const RawImage& img, ByteStream bs, int bps,
bool uncorrectedRawValues_);
void decompress();
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.cpp
index fc037af73..69572bf16 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.cpp
@@ -20,12 +20,13 @@
*/
#include "decompressors/LJpegDecompressor.h"
-#include "common/Common.h" // for uint32, unroll_loop, ushort16
+#include "common/Common.h" // for unroll_loop, uint32, ushort16
#include "common/Point.h" // for iPoint2D
#include "common/RawImage.h" // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "io/BitPumpJPEG.h" // for BitPumpJPEG
-#include <algorithm> // for min, copy_n
+#include "io/BitPumpJPEG.h" // for BitPumpJPEG, BitStream<>::...
+#include <algorithm> // for copy_n
+#include <cassert> // for assert
using std::copy_n;
@@ -94,38 +95,62 @@ void LJpegDecompressor::decodeScan()
if ((mRaw->getCpp() * (mRaw->dim.x - offX)) < frame.cps)
ThrowRDE("Got less pixels than the components per sample");
- const auto tilePixelBlocks = mRaw->getCpp() * w;
- if (tilePixelBlocks % frame.cps != 0) {
- ThrowRDE("Tile component width (%u) is not multiple of LJpeg CPS (%u)",
- tilePixelBlocks, frame.cps);
- }
+ // How many output pixels are we expected to produce, as per DNG tiling?
+ const auto tileRequiredWidth = mRaw->getCpp() * w;
- wBlocks = tilePixelBlocks / frame.cps;
- if (frame.w < wBlocks || frame.h < h) {
+ // How many full pixel blocks do we need to consume for that?
+ const auto blocksToConsume = roundUpDivision(tileRequiredWidth, frame.cps);
+ if (frame.w < blocksToConsume || frame.h < h) {
ThrowRDE("LJpeg frame (%u, %u) is smaller than expected (%u, %u)",
- frame.cps * frame.w, frame.h, tilePixelBlocks, h);
+ frame.cps * frame.w, frame.h, tileRequiredWidth, h);
}
- switch (frame.cps) {
- case 2:
- decodeN<2>();
- break;
- case 3:
- decodeN<3>();
- break;
- case 4:
- decodeN<4>();
- break;
- default:
- ThrowRDE("Unsupported number of components: %u", frame.cps);
+ // How many full pixel blocks will we produce?
+ fullBlocks = tileRequiredWidth / frame.cps; // Truncating division!
+ // Do we need to also produce part of a block?
+ trailingPixels = tileRequiredWidth % frame.cps;
+
+ if (trailingPixels == 0) {
+ switch (frame.cps) {
+ case 1:
+ decodeN<1>();
+ break;
+ case 2:
+ decodeN<2>();
+ break;
+ case 3:
+ decodeN<3>();
+ break;
+ case 4:
+ decodeN<4>();
+ break;
+ default:
+ ThrowRDE("Unsupported number of components: %u", frame.cps);
+ }
+ } else /* trailingPixels != 0 */ {
+ // FIXME: using different function just for one tile likely causes
+ // i-cache misses and whatnot. Need to check how not splitting it into
+ // two different functions affects performance of the normal case.
+ switch (frame.cps) {
+ // Naturally can't happen for CPS=1.
+ case 2:
+ decodeN<2, /*WeirdWidth=*/true>();
+ break;
+ case 3:
+ decodeN<3, /*WeirdWidth=*/true>();
+ break;
+ case 4:
+ decodeN<4, /*WeirdWidth=*/true>();
+ break;
+ default:
+ ThrowRDE("Unsupported number of components: %u", frame.cps);
+ }
}
}
// N_COMP == number of components (2, 3 or 4)
-template <int N_COMP>
-void LJpegDecompressor::decodeN()
-{
+template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
assert(mRaw->getCpp() > 0);
assert(N_COMP > 0);
assert(N_COMP >= mRaw->getCpp());
@@ -160,14 +185,38 @@ void LJpegDecompressor::decodeN()
// the predictor for the next line is the start of this line
predNext = dest;
- // For x, we first process all pixels within the image buffer ...
- for (unsigned x = 0; x < wBlocks; ++x) {
+ unsigned x = 0;
+
+ // For x, we first process all full pixel blocks within the image buffer ...
+ for (; x < fullBlocks; ++x) {
unroll_loop<N_COMP>([&](int i) {
*dest++ = pred[i] += ht[i]->decodeNext(bitStream);
});
}
+
+ // Sometimes we also need to consume one more block, and produce part of it.
+ if /*constexpr*/ (WeirdWidth) {
+ // FIXME: evaluate i-cache implications due to this being compile-time.
+ static_assert(N_COMP > 1 || !WeirdWidth,
+ "can't want part of 1-pixel-wide block");
+ // Some rather esoteric DNG's have odd dimensions, e.g. width % 2 = 1.
+ // We may end up needing just part of last N_COMP pixels.
+ assert(trailingPixels > 0);
+ assert(trailingPixels < N_COMP);
+ unsigned c = 0;
+ for (; c < trailingPixels; ++c) {
+ *dest++ = pred[c] += ht[c]->decodeNext(bitStream);
+ }
+ // Discard the rest of the block.
+ assert(c < N_COMP);
+ for (; c < N_COMP; ++c) {
+ ht[c]->decodeNext(bitStream);
+ }
+ ++x; // We did just process one more block.
+ }
+
// ... and discard the rest.
- for (unsigned x = wBlocks; x < frame.w; ++x) {
+ for (; x < frame.w; ++x) {
unroll_loop<N_COMP>([&](int i) {
ht[i]->decodeNext(bitStream);
});
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.h
index 41e51c1e5..d2783a85b 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.h
@@ -22,11 +22,10 @@
#include "common/Common.h" // for uint32
#include "decompressors/AbstractLJpegDecompressor.h" // for AbstractLJpegDe...
-#include "io/Buffer.h" // for Buffer, Buffer:...
-#include "io/ByteStream.h" // for ByteStream
namespace rawspeed {
+class ByteStream;
class RawImage;
// Decompresses Lossless JPEGs, with 2-4 components
@@ -34,20 +33,21 @@ class RawImage;
class LJpegDecompressor final : public AbstractLJpegDecompressor
{
void decodeScan() override;
- template<int N_COMP> void decodeN();
+ template <int N_COMP, bool WeirdWidth = false> void decodeN();
uint32 offX = 0;
uint32 offY = 0;
uint32 w = 0;
uint32 h = 0;
- uint32 wBlocks = 0;
+ uint32 fullBlocks = 0;
+ uint32 trailingPixels = 0;
public:
LJpegDecompressor(const ByteStream& bs, const RawImage& img);
void decode(uint32 offsetX, uint32 offsetY, uint32 width, uint32 height,
- bool fixDng16Bug);
+ bool fixDng16Bug_);
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.cpp
index d8c0d7962..f07a60f81 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.cpp
@@ -19,44 +19,352 @@
*/
#include "decompressors/NikonDecompressor.h"
-#include "common/Common.h" // for uint32, ushort16, clampBits
+#include "common/Common.h" // for uint32, clampBits, ushort16
#include "common/Point.h" // for iPoint2D
-#include "common/RawImage.h" // for RawImage, RawImageData, RawI...
+#include "common/RawImage.h" // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/HuffmanTable.h" // for HuffmanTable
-#include "io/BitPumpMSB.h" // for BitPumpMSB, BitStream<>::fil...
+#include "io/BitPumpMSB.h" // for BitPumpMSB, BitStream<>::f...
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include <cstdio> // for size_t, NULL
-#include <vector> // for vector, allocator
+#include <cassert> // for assert
+#include <cstdio> // for size_t
+#include <vector> // for vector
namespace rawspeed {
-const uchar8 NikonDecompressor::nikon_tree[][2][16] = {
- {/* 12-bit lossy */
- {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
- {5, 4, 3, 6, 2, 7, 1, 0, 8, 9, 11, 10, 12}},
- {/* 12-bit lossy after split */
- {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
- {0x39, 0x5a, 0x38, 0x27, 0x16, 5, 4, 3, 2, 1, 0, 11, 12, 12}},
- {/* 12-bit lossless */
- {0, 1, 4, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- {5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, 11, 12}},
- {/* 14-bit lossy */
- {0, 1, 4, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
- {5, 6, 4, 7, 8, 3, 9, 2, 1, 0, 10, 11, 12, 13, 14}},
- {/* 14-bit lossy after split */
- {0, 1, 5, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0},
- {8, 0x5c, 0x4b, 0x3a, 0x29, 7, 6, 5, 4, 3, 2, 1, 0, 13, 14}},
- {/* 14-bit lossless */
- {0, 1, 4, 2, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0},
- {7, 6, 8, 5, 9, 4, 10, 3, 11, 12, 2, 0, 1, 13, 14}},
+const std::array<std::array<std::array<uchar8, 16>, 2>, 6>
+ NikonDecompressor::nikon_tree = {{
+ {{/* 12-bit lossy */
+ {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ {5, 4, 3, 6, 2, 7, 1, 0, 8, 9, 11, 10, 12}}},
+ {{/* 12-bit lossy after split */
+ {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ {0x39, 0x5a, 0x38, 0x27, 0x16, 5, 4, 3, 2, 1, 0, 11, 12, 12}}},
+ {{/* 12-bit lossless */
+ {0, 1, 4, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, 11, 12}}},
+ {{/* 14-bit lossy */
+ {0, 1, 4, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ {5, 6, 4, 7, 8, 3, 9, 2, 1, 0, 10, 11, 12, 13, 14}}},
+ {{/* 14-bit lossy after split */
+ {0, 1, 5, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0},
+ {8, 0x5c, 0x4b, 0x3a, 0x29, 7, 6, 5, 4, 3, 2, 1, 0, 13, 14}}},
+ {{/* 14-bit lossless */
+ {0, 1, 4, 2, 2, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0},
+ {7, 6, 8, 5, 9, 4, 10, 3, 11, 12, 2, 0, 1, 13, 14}}},
+ }};
+
+namespace {
+
+const std::array<uint32, 32> bitMask = {
+ {0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff, 0x0fffffff, 0x07ffffff,
+ 0x03ffffff, 0x01ffffff, 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
+ 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
+ 0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
+ 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f, 0x0000000f, 0x00000007,
+ 0x00000003, 0x00000001}};
+
+class NikonLASDecompressor {
+ bool mUseBigtable = true;
+ bool mDNGCompatible = false;
+
+ struct HuffmanTable {
+ /*
+ * These two fields directly represent the contents of a JPEG DHT
+ * marker
+ */
+ std::array<uint32, 17> bits;
+ std::array<uint32, 256> huffval;
+
+ /*
+ * The remaining fields are computed from the above to allow more
+ * efficient coding and decoding. These fields should be considered
+ * private to the Huffman compression & decompression modules.
+ */
+
+ std::array<ushort16, 17> mincode;
+ std::array<int, 18> maxcode;
+ std::array<short, 17> valptr;
+ std::array<uint32, 256> numbits;
+ std::vector<int> bigTable;
+ bool initialized;
+ } dctbl1;
+
+ void createHuffmanTable() {
+ int p;
+ int i;
+ int l;
+ int lastp;
+ int si;
+ std::array<char, 257> huffsize;
+ std::array<ushort16, 257> huffcode;
+ ushort16 code;
+ int size;
+ int value;
+ int ll;
+ int ul;
+
+ /*
+ * Figure C.1: make table of Huffman code length for each symbol
+ * Note that this is in code-length order.
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ for (i = 1; i <= static_cast<int>(dctbl1.bits[l]); i++) {
+ huffsize[p++] = static_cast<char>(l);
+ if (p > 256)
+ ThrowRDE("LJpegDecompressor::createHuffmanTable: Code length too "
+ "long. Corrupt data.");
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ /*
+ * Figure C.2: generate the codes themselves
+ * Note that this is in code-length order.
+ */
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while ((static_cast<int>(huffsize[p])) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ if (p > 256)
+ ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
+ }
+
+ /*
+ * Figure F.15: generate decoding tables
+ */
+ dctbl1.mincode[0] = 0;
+ dctbl1.maxcode[0] = 0;
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ if (dctbl1.bits[l]) {
+ dctbl1.valptr[l] = p;
+ dctbl1.mincode[l] = huffcode[p];
+ p += dctbl1.bits[l];
+ dctbl1.maxcode[l] = huffcode[p - 1];
+ } else {
+ dctbl1.valptr[l] =
+ 0xff; // This check must be present to avoid crash on junk
+ dctbl1.maxcode[l] = -1;
+ }
+ if (p > 256)
+ ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
+ }
+
+ /*
+ * We put in this value to ensure HuffDecode terminates.
+ */
+ dctbl1.maxcode[17] = 0xFFFFFL;
+
+ /*
+ * Build the numbits, value lookup tables.
+ * These table allow us to gather 8 bits from the bits stream,
+ * and immediately lookup the size and value of the huffman codes.
+ * If size is zero, it means that more than 8 bits are in the huffman
+ * code (this happens about 3-4% of the time).
+ */
+ dctbl1.numbits.fill(0);
+ for (p = 0; p < lastp; p++) {
+ size = huffsize[p];
+ if (size <= 8) {
+ value = dctbl1.huffval[p];
+ code = huffcode[p];
+ ll = code << (8 - size);
+ if (size < 8) {
+ ul = ll | bitMask[24 + size];
+ } else {
+ ul = ll;
+ }
+ if (ul > 256 || ll > ul)
+ ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
+ for (i = ll; i <= ul; i++) {
+ dctbl1.numbits[i] = size | (value << 4);
+ }
+ }
+ }
+ if (mUseBigtable)
+ createBigTable();
+ dctbl1.initialized = true;
+ }
+
+ /************************************
+ * Bitable creation
+ *
+ * This is expanding the concept of fast lookups
+ *
+ * A complete table for 14 arbitrary bits will be
+ * created that enables fast lookup of number of bits used,
+ * and final delta result.
+ * Hit rate is about 90-99% for typical LJPEGS, usually about 98%
+ *
+ ************************************/
+
+ void createBigTable() {
+ const uint32 bits =
+ 14; // HuffDecode functions must be changed, if this is modified.
+ const uint32 size = 1 << bits;
+ int rv = 0;
+ int temp;
+ uint32 l;
+
+ dctbl1.bigTable.resize(size);
+ for (uint32 i = 0; i < size; i++) {
+ ushort16 input = i << 2; // Calculate input value
+ int code = input >> 8; // Get 8 bits
+ uint32 val = dctbl1.numbits[code];
+ l = val & 15;
+ if (l) {
+ rv = val >> 4;
+ } else {
+ l = 8;
+ while (code > dctbl1.maxcode[l]) {
+ temp = input >> (15 - l) & 1;
+ code = (code << 1) | temp;
+ l++;
+ }
+
+ /*
+ * With garbage input we may reach the sentinel value l = 17.
+ */
+
+ if (l > 16 || dctbl1.valptr[l] == 0xff) {
+ dctbl1.bigTable[i] = 0xff;
+ continue;
+ }
+ rv = dctbl1.huffval[dctbl1.valptr[l] + (code - dctbl1.mincode[l])];
+ }
+
+ if (rv == 16) {
+ if (mDNGCompatible)
+ dctbl1.bigTable[i] = (-(32768 << 8)) | (16 + l);
+ else
+ dctbl1.bigTable[i] = (-(32768 << 8)) | l;
+ continue;
+ }
+
+ if (rv + l > bits) {
+ dctbl1.bigTable[i] = 0xff;
+ continue;
+ }
+
+ if (rv) {
+ int x = input >> (16 - l - rv) & ((1 << rv) - 1);
+ if ((x & (1 << (rv - 1))) == 0)
+ x -= (1 << rv) - 1;
+ dctbl1.bigTable[i] =
+ static_cast<int>((static_cast<unsigned>(x) << 8) | (l + rv));
+ } else {
+ dctbl1.bigTable[i] = l;
+ }
+ }
+ }
+
+public:
+ uint32 setNCodesPerLength(const Buffer& data) {
+ uint32 acc = 0;
+ for (uint32 i = 0; i < 16; i++) {
+ dctbl1.bits[i + 1] = data[i];
+ acc += dctbl1.bits[i + 1];
+ }
+ dctbl1.bits[0] = 0;
+ return acc;
+ }
+
+ void setCodeValues(const Buffer& data) {
+ for (uint32 i = 0; i < data.getSize(); i++)
+ dctbl1.huffval[i] = data[i];
+ }
+
+ void setup(bool fullDecode_, bool fixDNGBug16_) { createHuffmanTable(); }
+
+ /*
+ *--------------------------------------------------------------
+ *
+ * HuffDecode --
+ *
+ * Taken from Figure F.16: extract next coded symbol from
+ * input stream. This should becode a macro.
+ *
+ * Results:
+ * Next coded symbol
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+ int decodeNext(BitPumpMSB& bits) { // NOLINT: google-runtime-references
+ int rv;
+ int l;
+ int temp;
+ int code;
+ unsigned val;
+
+ bits.fill();
+ code = bits.peekBitsNoFill(14);
+ val = static_cast<unsigned>(dctbl1.bigTable[code]);
+ if ((val & 0xff) != 0xff) {
+ bits.skipBitsNoFill(val & 0xff);
+ return static_cast<int>(val) >> 8;
+ }
+ rv = 0;
+ code = bits.peekBitsNoFill(8);
+ val = dctbl1.numbits[code];
+ l = val & 15;
+ if (l) {
+ bits.skipBitsNoFill(l);
+ rv = static_cast<int>(val) >> 4;
+ } else {
+ bits.skipBits(8);
+ l = 8;
+ while (code > dctbl1.maxcode[l]) {
+ temp = bits.getBitsNoFill(1);
+ code = (code << 1) | temp;
+ l++;
+ }
+
+ if (l > 16) {
+ ThrowRDE("Corrupt JPEG data: bad Huffman code:%u\n", l);
+ } else {
+ rv = dctbl1.huffval[dctbl1.valptr[l] + (code - dctbl1.mincode[l])];
+ }
+ }
+
+ if (rv == 16)
+ return -32768;
+
+ /*
+ * Section F.2.2.1: decode the difference and
+ * Figure F.12: extend sign bit
+ */
+ uint32 len = rv & 15;
+ uint32 shl = rv >> 4;
+ int diff = ((bits.getBits(len - shl) << 1) + 1) << shl >> 1;
+ if ((diff & (1 << (len - 1))) == 0)
+ diff -= (1 << len) - !shl;
+ return diff;
+ }
};
+} // namespace
+
std::vector<ushort16> NikonDecompressor::createCurve(ByteStream* metadata,
uint32 bitsPS, uint32 v0,
uint32 v1, uint32* split) {
+ // Nikon Z7 12/14 bit compressed hack.
+ if (v0 == 68 && v1 == 64)
+ bitsPS -= 2;
+
// 'curve' will hold a peace wise linearly interpolated function.
// there are 'csize' segments, each is 'step' values long.
// the very last value is not part of the used table but necessary
@@ -73,7 +381,7 @@ std::vector<ushort16> NikonDecompressor::createCurve(ByteStream* metadata,
if (csize > 1)
step = curve.size() / (csize - 1);
- if (v0 == 68 && v1 == 32 && step > 0) {
+ if (v0 == 68 && (v1 == 32 || v1 == 64) && step > 0) {
if ((csize - 1) * step != curve.size() - 1)
ThrowRDE("Bad curve segment count (%u)", csize);
@@ -114,15 +422,18 @@ std::vector<ushort16> NikonDecompressor::createCurve(ByteStream* metadata,
return curve;
}
-HuffmanTable NikonDecompressor::createHuffmanTable(uint32 huffSelect) {
- HuffmanTable ht;
- uint32 count = ht.setNCodesPerLength(Buffer(nikon_tree[huffSelect][0], 16));
- ht.setCodeValues(Buffer(nikon_tree[huffSelect][1], count));
+template <typename Huffman>
+Huffman NikonDecompressor::createHuffmanTable(uint32 huffSelect) {
+ Huffman ht;
+ uint32 count =
+ ht.setNCodesPerLength(Buffer(nikon_tree[huffSelect][0].data(), 16));
+ ht.setCodeValues(Buffer(nikon_tree[huffSelect][1].data(), count));
ht.setup(true, false);
return ht;
}
-NikonDecompressor::NikonDecompressor(const RawImage& raw, uint32 bitsPS_)
+NikonDecompressor::NikonDecompressor(const RawImage& raw, ByteStream metadata,
+ uint32 bitsPS_)
: mRaw(raw), bitsPS(bitsPS_) {
if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
mRaw->getBpp() != 2)
@@ -140,18 +451,9 @@ NikonDecompressor::NikonDecompressor(const RawImage& raw, uint32 bitsPS_)
default:
ThrowRDE("Invalid bpp found: %u", bitsPS);
}
-}
-
-void NikonDecompressor::decompress(ByteStream metadata, const ByteStream& data,
- bool uncorrectedRawValues) {
- const iPoint2D& size = mRaw->dim;
uint32 v0 = metadata.getByte();
uint32 v1 = metadata.getByte();
- uint32 huffSelect = 0;
- uint32 split = 0;
- int pUp1[2];
- int pUp2[2];
writeLog(DEBUG_PRIO_EXTRA, "Nef version v0:%u, v1:%u", v0, v1);
@@ -168,33 +470,36 @@ void NikonDecompressor::decompress(ByteStream metadata, const ByteStream& data,
pUp2[0] = metadata.getU16();
pUp2[1] = metadata.getU16();
- HuffmanTable ht = createHuffmanTable(huffSelect);
+ curve = createCurve(&metadata, bitsPS, v0, v1, &split);
- auto curve = createCurve(&metadata, bitsPS, v0, v1, &split);
- RawImageCurveGuard curveHandler(&mRaw, curve, uncorrectedRawValues);
+ // If the 'split' happens outside of the image, it does not actually happen.
+ if (split >= static_cast<unsigned>(mRaw->dim.y))
+ split = 0;
+}
+
+template <typename Huffman>
+void NikonDecompressor::decompress(BitPumpMSB* bits, int start_y, int end_y) {
+ Huffman ht = createHuffmanTable<Huffman>(huffSelect);
- BitPumpMSB bits(data);
uchar8* draw = mRaw->getData();
uint32 pitch = mRaw->pitch;
int pLeft1 = 0;
int pLeft2 = 0;
- uint32 random = bits.peekBits(24);
- //allow gcc to devirtualize the calls below
+
+ // allow gcc to devirtualize the calls below
auto* rawdata = reinterpret_cast<RawImageDataU16*>(mRaw.get());
+ const iPoint2D& size = mRaw->dim;
assert(size.x % 2 == 0);
assert(size.x >= 2);
- for (uint32 y = 0; y < static_cast<unsigned>(size.y); y++) {
- if (split && y == split) {
- ht = createHuffmanTable(huffSelect + 1);
- }
+ for (uint32 y = start_y; y < static_cast<uint32>(end_y); y++) {
auto* dest =
reinterpret_cast<ushort16*>(&draw[y * pitch]); // Adjust destination
- pUp1[y&1] += ht.decodeNext(bits);
- pUp2[y&1] += ht.decodeNext(bits);
- pLeft1 = pUp1[y&1];
- pLeft2 = pUp2[y&1];
+ pUp1[y & 1] += ht.decodeNext(*bits);
+ pUp2[y & 1] += ht.decodeNext(*bits);
+ pLeft1 = pUp1[y & 1];
+ pLeft2 = pUp2[y & 1];
rawdata->setWithLookUp(clampBits(pLeft1, 15),
reinterpret_cast<uchar8*>(dest + 0), &random);
@@ -204,8 +509,8 @@ void NikonDecompressor::decompress(ByteStream metadata, const ByteStream& data,
dest += 2;
for (uint32 x = 2; x < static_cast<uint32>(size.x); x += 2) {
- pLeft1 += ht.decodeNext(bits);
- pLeft2 += ht.decodeNext(bits);
+ pLeft1 += ht.decodeNext(*bits);
+ pLeft2 += ht.decodeNext(*bits);
rawdata->setWithLookUp(clampBits(pLeft1, 15),
reinterpret_cast<uchar8*>(dest + 0), &random);
@@ -217,4 +522,23 @@ void NikonDecompressor::decompress(ByteStream metadata, const ByteStream& data,
}
}
+void NikonDecompressor::decompress(const ByteStream& data,
+ bool uncorrectedRawValues) {
+ RawImageCurveGuard curveHandler(&mRaw, curve, uncorrectedRawValues);
+
+ BitPumpMSB bits(data);
+
+ random = bits.peekBits(24);
+
+ assert(split == 0 || split < static_cast<unsigned>(mRaw->dim.y));
+
+ if (!split) {
+ decompress<HuffmanTable>(&bits, 0, mRaw->dim.y);
+ } else {
+ decompress<HuffmanTable>(&bits, 0, split);
+ huffSelect += 1;
+ decompress<NikonLASDecompressor>(&bits, split, mRaw->dim.y);
+ }
+}
+
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.h
index 6fde227a5..cfa1bb0e5 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/NikonDecompressor.h
@@ -20,36 +20,45 @@
#pragma once
-#include "common/Common.h" // for uint32
+#include "common/Common.h" // for uint32, ushort16
#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
+#include "io/BitPumpMSB.h" // for BitPumpMSB
#include <vector> // for vector
namespace rawspeed {
-class iPoint2D;
-
-class RawImage;
-
class ByteStream;
-class HuffmanTable;
-
class NikonDecompressor final : public AbstractDecompressor {
RawImage mRaw;
uint32 bitsPS;
+ uint32 huffSelect = 0;
+ uint32 split = 0;
+
+ std::array<int, 2> pUp1;
+ std::array<int, 2> pUp2;
+
+ std::vector<ushort16> curve;
+
+ uint32 random;
+
public:
- NikonDecompressor(const RawImage& raw, uint32 bitsPS);
+ NikonDecompressor(const RawImage& raw, ByteStream metadata, uint32 bitsPS);
- void decompress(ByteStream metadata, const ByteStream& data,
- bool uncorrectedRawValues);
+ void decompress(const ByteStream& data, bool uncorrectedRawValues);
private:
- static const uchar8 nikon_tree[][2][16];
+ static const std::array<std::array<std::array<uchar8, 16>, 2>, 6> nikon_tree;
static std::vector<ushort16> createCurve(ByteStream* metadata, uint32 bitsPS,
uint32 v0, uint32 v1, uint32* split);
- static HuffmanTable createHuffmanTable(uint32 huffSelect);
+
+ template <typename Huffman>
+ void decompress(BitPumpMSB* bits, int start_y, int end_y);
+
+ template <typename Huffman>
+ static Huffman createHuffmanTable(uint32 huffSelect);
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.cpp
index 3a8cc3399..5f6ceb680 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.cpp
@@ -21,20 +21,19 @@
*/
#include "decompressors/OlympusDecompressor.h"
-#include "common/Common.h" // for uchar8
-#include "common/Point.h" // for iPoint2D
-#include "common/RawImage.h" // for RawImage
-#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "decompressors/AbstractDecompressor.h" // for RawDecom...
-#include "decompressors/HuffmanTable.h" // for HuffmanTable
-#include "io/BitPumpMSB.h" // for BitPumpMSB
-#include <algorithm> // for move
-#include <algorithm> // for min
-#include <array> // for array
-#include <cmath> // for signbit
-#include <cstdlib> // for abs
-#include <memory> // for unique_ptr
-#include <type_traits> // for enable_if, is_integer
+#include "common/Common.h" // for uint32, ushort16, uchar8
+#include "common/Point.h" // for iPoint2D
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "io/BitPumpMSB.h" // for BitPumpMSB
+#include "io/ByteStream.h" // for ByteStream
+#include <algorithm> // for min
+#include <array> // for array, array<>::value_type
+#include <cassert> // for assert
+#include <cmath> // for abs
+#include <cstdlib> // for abs
+#include <memory> // for unique_ptr
+#include <type_traits> // for enable_if_t, is_integral
namespace {
@@ -90,7 +89,7 @@ void OlympusDecompressor::decompress(ByteStream input) const {
int pitch = mRaw->pitch;
/* Build a table to quickly look up "high" value */
- std::unique_ptr<char[]> bittable(new char[4096]);
+ std::unique_ptr<char[]> bittable(new char[4096]); // NOLINT
for (i = 0; i < 4096; i++) {
int b = i;
@@ -146,9 +145,10 @@ void OlympusDecompressor::decompress(ByteStream input) const {
nw[c] = pred;
}
}
- dest[x] = pred + ((diff * 4) | low);
// Set predictor
- left[c] = dest[x];
+ left[c] = pred + ((diff * 4) | low);
+ // Set the pixel
+ dest[x] = left[c];
} else {
// Have local variables for values used several tiles
// (having a "ushort16 *dst_up" that caches dest[-pitch+((int)x)] is
@@ -166,10 +166,11 @@ void OlympusDecompressor::decompress(ByteStream input) const {
} else
pred = std::abs(leftMinusNw) > std::abs(upMinusNw) ? left[c] : up;
- dest[x] = pred + ((diff * 4) | low);
// Set predictors
- left[c] = dest[x];
+ left[c] = pred + ((diff * 4) | low);
nw[c] = up;
+ // Set the pixel
+ dest[x] = left[c];
}
// ODD PIXELS
@@ -208,7 +209,10 @@ void OlympusDecompressor::decompress(ByteStream input) const {
nw[c] = pred;
}
}
- dest[x] = left[c] = pred + ((diff * 4) | low);
+ // Set predictor
+ left[c] = pred + ((diff * 4) | low);
+ // Set the pixel
+ dest[x] = left[c];
} else {
int up = dest[-pitch + (static_cast<int>(x))];
int leftMinusNw = left[c] - nw[c];
@@ -224,8 +228,11 @@ void OlympusDecompressor::decompress(ByteStream input) const {
} else
pred = std::abs(leftMinusNw) > std::abs(upMinusNw) ? left[c] : up;
- dest[x] = left[c] = pred + ((diff * 4) | low);
+ // Set predictors
+ left[c] = pred + ((diff * 4) | low);
nw[c] = up;
+ // Set the pixel
+ dest[x] = left[c];
}
border = y_border;
}
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.h
index bb9ebc1b6..c52561394 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/OlympusDecompressor.h
@@ -22,11 +22,10 @@
#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
-#include "io/ByteStream.h" // for ByteStream
namespace rawspeed {
-class RawImage;
+class ByteStream;
class OlympusDecompressor final : public AbstractDecompressor {
RawImage mRaw;
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.cpp
index c7c982f13..a1dd4cd34 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.cpp
@@ -3,7 +3,7 @@
Copyright (C) 2009-2014 Klaus Post
Copyright (C) 2014 Pedro Côrte-Real
- Copyright (C) 2017 Roman Lebedev
+ Copyright (C) 2017-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
@@ -21,153 +21,230 @@
*/
#include "decompressors/PanasonicDecompressor.h"
-#include "common/Mutex.h" // for MutexLocker
-#include "common/Point.h" // for iPoint2D
-#include "common/RawImage.h" // for RawImage, RawImageData
-#include <algorithm> // for min, move
-#include <cstring> // for memcpy
-#include <vector> // for vector
+#include "common/Mutex.h" // for MutexLocker
+#include "common/Point.h" // for iPoint2D
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "io/Buffer.h" // for Buffer, Buffer::size_type
+#include <algorithm> // for generate_n, min
+#include <array> // for array
+#include <cassert> // for assert
+#include <cstddef> // for size_t
+#include <iterator> // for back_insert_iterator, back...
+#include <limits> // for numeric_limits
+#include <memory> // for allocator_traits<>::value_...
+#include <utility> // for move
+#include <vector> // for vector
namespace rawspeed {
+constexpr uint32 PanasonicDecompressor::BlockSize;
+
PanasonicDecompressor::PanasonicDecompressor(const RawImage& img,
const ByteStream& input_,
bool zero_is_not_bad,
- uint32 load_flags_)
+ uint32 section_split_offset_)
: AbstractParallelizedDecompressor(img), zero_is_bad(!zero_is_not_bad),
- load_flags(load_flags_) {
+ section_split_offset(section_split_offset_) {
if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
mRaw->getBpp() != 2)
ThrowRDE("Unexpected component count / data type");
- if (!mRaw->dim.hasPositiveArea() || mRaw->dim.x % 14 != 0) {
+ if (!mRaw->dim.hasPositiveArea() || mRaw->dim.x % PixelsPerPacket != 0) {
ThrowRDE("Unexpected image dimensions found: (%i; %i)", mRaw->dim.x,
mRaw->dim.y);
}
- /*
- * Normally, we would check the image dimensions against some hardcoded
- * threshold. That is being done as poor man's attempt to catch
- * obviously-invalid raws, and avoid OOM's during fuzzing. However, there is
- * a better solution - actually check the size of input buffer to try and
- * guess whether the image size is valid or not. And in this case, we can do
- * that, because the compression rate is static and known.
- */
- // if (width > 5488 || height > 3912)
- // ThrowRDE("Too large image size: (%u; %u)", width, height);
-
- if (BufSize < load_flags)
- ThrowRDE("Bad load_flags: %u, less than BufSize (%u)", load_flags, BufSize);
+ if (BlockSize < section_split_offset)
+ ThrowRDE("Bad section_split_offset: %u, less than BlockSize (%u)",
+ section_split_offset, BlockSize);
// Naive count of bytes that given pixel count requires.
- // Do division first, because we know the remainder is always zero,
- // and the next multiplication won't overflow.
- assert(mRaw->dim.area() % 7ULL == 0ULL);
- const auto rawBytesNormal = (mRaw->dim.area() / 7ULL) * 8ULL;
- // If load_flags is zero, than that size is the size we need to read.
- // But if it is not, then we need to round up to multiple of BufSize, because
- // of splitting&rotation of each BufSize's slice in half at load_flags bytes.
+ assert(mRaw->dim.area() % PixelsPerPacket == 0);
+ const auto bytesTotal = (mRaw->dim.area() / PixelsPerPacket) * BytesPerPacket;
+ assert(bytesTotal > 0);
+
+ // If section_split_offset is zero, then that we need to read the normal
+ // amount of bytes. But if it is not, then we need to round up to multiple of
+ // BlockSize, because of splitting&rotation of each BlockSize's slice in half
+ // at section_split_offset bytes.
const auto bufSize =
- load_flags == 0 ? rawBytesNormal : roundUp(rawBytesNormal, BufSize);
+ section_split_offset == 0 ? bytesTotal : roundUp(bytesTotal, BlockSize);
+
+ if (bufSize > std::numeric_limits<ByteStream::size_type>::max())
+ ThrowRDE("Raw dimensions require input buffer larger than supported");
+
input = input_.peekStream(bufSize);
+
+ chopInputIntoBlocks();
}
-struct PanasonicDecompressor::PanaBitpump {
- ByteStream input;
+void PanasonicDecompressor::chopInputIntoBlocks() {
+ auto pixelToCoordinate = [width = mRaw->dim.x](unsigned pixel) -> iPoint2D {
+ return iPoint2D(pixel % width, pixel / width);
+ };
+
+ // If section_split_offset == 0, last block may not be full.
+ const auto blocksTotal = roundUpDivision(input.getRemainSize(), BlockSize);
+ assert(blocksTotal > 0);
+ assert(blocksTotal * PixelsPerBlock >= mRaw->dim.area());
+ blocks.reserve(blocksTotal);
+
+ unsigned currPixel = 0;
+ std::generate_n(std::back_inserter(blocks), blocksTotal,
+ [input = &input, &currPixel, pixelToCoordinate]() -> Block {
+ assert(input->getRemainSize() != 0);
+ const auto blockSize =
+ std::min(input->getRemainSize(), BlockSize);
+ assert(blockSize > 0);
+ assert(blockSize % BytesPerPacket == 0);
+ const auto packets = blockSize / BytesPerPacket;
+ assert(packets > 0);
+ const auto pixels = packets * PixelsPerPacket;
+ assert(pixels > 0);
+
+ ByteStream bs = input->getStream(blockSize);
+ iPoint2D beginCoord = pixelToCoordinate(currPixel);
+ currPixel += pixels;
+ iPoint2D endCoord = pixelToCoordinate(currPixel);
+ return {std::move(bs), beginCoord, endCoord};
+ });
+ assert(blocks.size() == blocksTotal);
+ assert(currPixel >= mRaw->dim.area());
+ assert(input.getRemainSize() == 0);
+
+ // Clamp the end coordinate for the last block.
+ blocks.back().endCoord = mRaw->dim;
+ blocks.back().endCoord.y -= 1;
+}
+
+class PanasonicDecompressor::ProxyStream {
+ ByteStream block;
+ const uint32 section_split_offset;
std::vector<uchar8> buf;
+
int vbits = 0;
- uint32 load_flags;
- PanaBitpump(ByteStream input_, int load_flags_)
- : input(std::move(input_)), load_flags(load_flags_) {
+ void parseBlock() {
+ assert(buf.empty());
+ assert(block.getRemainSize() <= BlockSize);
+ assert(section_split_offset <= BlockSize);
+
+ Buffer FirstSection = block.getBuffer(section_split_offset);
+ Buffer SecondSection = block.getBuffer(block.getRemainSize());
+
+ // get one more byte, so the return statement of getBits does not have
+ // to special case for accessing the last byte
+ buf.reserve(BlockSize + 1UL);
+
+ // First copy the second section. This makes it the first section.
+ buf.insert(buf.end(), SecondSection.begin(), SecondSection.end());
+ // Now append the original 1'st section right after the new 1'st section.
+ buf.insert(buf.end(), FirstSection.begin(), FirstSection.end());
+
+ assert(block.getRemainSize() == 0);
+
// get one more byte, so the return statement of getBits does not have
// to special case for accessing the last byte
- buf.resize(BufSize + 1UL);
+ buf.emplace_back(0);
}
- void skipBytes(int bytes) {
- int blocks = (bytes / BufSize) * BufSize;
- input.skipBytes(blocks);
- for (int i = blocks; i < bytes; i++)
- (void)getBits(8);
+public:
+ ProxyStream(ByteStream block_, int section_split_offset_)
+ : block(std::move(block_)), section_split_offset(section_split_offset_) {
+ parseBlock();
}
uint32 getBits(int nbits) {
- if (!vbits) {
- /* On truncated files this routine will just return just for the truncated
- * part of the file. Since there is no chance of affecting output buffer
- * size we allow the decoder to decode this
- */
- assert(BufSize >= load_flags);
- auto size = std::min(input.getRemainSize(), BufSize - load_flags);
- memcpy(buf.data() + load_flags, input.getData(size), size);
-
- size = std::min(input.getRemainSize(), load_flags);
- if (size != 0)
- memcpy(buf.data(), input.getData(size), size);
- }
vbits = (vbits - nbits) & 0x1ffff;
int byte = vbits >> 3 ^ 0x3ff0;
return (buf[byte] | buf[byte + 1UL] << 8) >> (vbits & 7) & ~(-(1 << nbits));
}
};
-void PanasonicDecompressor::decompressThreaded(
- const RawDecompressorThread* t) const {
- PanaBitpump bits(input, load_flags);
+void PanasonicDecompressor::processPixelPacket(
+ ProxyStream* bits, int y, ushort16* dest, int xbegin,
+ std::vector<uint32>* zero_pos) const {
+ int sh = 0;
- /* 9 + 1/7 bits per pixel */
- bits.skipBytes(8 * mRaw->dim.x * t->start / 7);
+ std::array<int, 2> pred;
+ pred.fill(0);
- assert(mRaw->dim.x % 14 == 0);
- const auto blocks = mRaw->dim.x / 14;
+ std::array<int, 2> nonz;
+ nonz.fill(0);
- std::vector<uint32> zero_pos;
- for (uint32 y = t->start; y < t->end; y++) {
- int sh = 0;
-
- auto* dest = reinterpret_cast<ushort16*>(mRaw->getData(0, y));
- for (int block = 0; block < blocks; block++) {
- std::array<int, 2> pred;
- pred.fill(0);
-
- std::array<int, 2> nonz;
- nonz.fill(0);
-
- int u = 0;
-
- for (int x = 0; x < 14; x++) {
- const int c = x & 1;
-
- if (u == 2) {
- sh = 4 >> (3 - bits.getBits(2));
- u = -1;
- }
-
- if (nonz[c]) {
- int j = bits.getBits(8);
- if (j) {
- pred[c] -= 0x80 << sh;
- if (pred[c] < 0 || sh == 4)
- pred[c] &= ~(-(1 << sh));
- pred[c] += j << sh;
- }
- } else {
- nonz[c] = bits.getBits(8);
- if (nonz[c] || x > 11)
- pred[c] = nonz[c] << 4 | bits.getBits(4);
- }
-
- *dest = pred[c];
-
- if (zero_is_bad && 0 == pred[c])
- zero_pos.push_back((y << 16) | (14 * block + x));
-
- u++;
- dest++;
+ int u = 0;
+
+ for (int p = 0; p < PixelsPerPacket; p++) {
+ const int c = p & 1;
+
+ if (u == 2) {
+ sh = 4 >> (3 - bits->getBits(2));
+ u = -1;
+ }
+
+ if (nonz[c]) {
+ int j = bits->getBits(8);
+ if (j) {
+ pred[c] -= 0x80 << sh;
+ if (pred[c] < 0 || sh == 4)
+ pred[c] &= ~(-(1 << sh));
+ pred[c] += j << sh;
}
+ } else {
+ nonz[c] = bits->getBits(8);
+ if (nonz[c] || p > 11)
+ pred[c] = nonz[c] << 4 | bits->getBits(4);
+ }
+
+ *dest = pred[c];
+
+ if (zero_is_bad && 0 == pred[c])
+ zero_pos->push_back((y << 16) | (xbegin + p));
+
+ u++;
+ dest++;
+ }
+}
+
+void PanasonicDecompressor::processBlock(const Block& block,
+ std::vector<uint32>* zero_pos) const {
+ ProxyStream bits(block.bs, section_split_offset);
+
+ for (int y = block.beginCoord.y; y <= block.endCoord.y; y++) {
+ int x = 0;
+ // First row may not begin at the first column.
+ if (block.beginCoord.y == y)
+ x = block.beginCoord.x;
+
+ int endx = mRaw->dim.x;
+ // Last row may end before the last column.
+ if (block.endCoord.y == y)
+ endx = block.endCoord.x;
+
+ auto* dest = reinterpret_cast<ushort16*>(mRaw->getData(x, y));
+
+ assert(x % PixelsPerPacket == 0);
+ assert(endx % PixelsPerPacket == 0);
+
+ for (; x < endx;) {
+ processPixelPacket(&bits, y, dest, x, zero_pos);
+
+ x += PixelsPerPacket;
+ dest += PixelsPerPacket;
}
}
+}
+
+void PanasonicDecompressor::decompressThreaded(
+ const RawDecompressorThread* t) const {
+ std::vector<uint32> zero_pos;
+
+ assert(!blocks.empty());
+ assert(t->start < t->end);
+ assert(t->end <= blocks.size());
+ for (size_t i = t->start; i < t->end; i++)
+ processBlock(blocks[i], &zero_pos);
if (zero_is_bad && !zero_pos.empty()) {
MutexLocker guard(&mRaw->mBadPixelMutex);
@@ -176,4 +253,9 @@ void PanasonicDecompressor::decompressThreaded(
}
}
+void PanasonicDecompressor::decompress() const {
+ assert(!blocks.empty());
+ startThreading(blocks.size());
+}
+
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.h
index 27480d489..68ef1f020 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressor.h
@@ -1,7 +1,7 @@
/*
RawSpeed - RAW file decoder.
- Copyright (C) 2017 Roman Lebedev
+ Copyright (C) 2017-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
@@ -21,33 +21,70 @@
#pragma once
#include "common/Common.h" // for uint32
+#include "common/Point.h" // for iPoint2D
#include "decompressors/AbstractParallelizedDecompressor.h" // for Abstract...
#include "io/ByteStream.h" // for ByteStream
+#include <utility> // for move
+#include <vector> // for vector
namespace rawspeed {
class RawImage;
class PanasonicDecompressor final : public AbstractParallelizedDecompressor {
- static constexpr uint32 BufSize = 0x4000;
- struct PanaBitpump;
+ static constexpr uint32 BlockSize = 0x4000;
- void decompressThreaded(const RawDecompressorThread* t) const final;
+ static constexpr int PixelsPerPacket = 14;
+
+ static constexpr uint32 BytesPerPacket = 16;
+
+ static constexpr uint32 PacketsPerBlock = BlockSize / BytesPerPacket;
+
+ static constexpr uint32 PixelsPerBlock = PixelsPerPacket * PacketsPerBlock;
+
+ class ProxyStream;
ByteStream input;
bool zero_is_bad;
// The RW2 raw image buffer is split into sections of BufSize bytes.
- // If load_flags is 0, then last section is not nessesairly full.
- // If load_flags is not 0, then each section has two parts:
- // bytes: [0..load_flags-1][load_flags..BufSize-1]
+ // If section_split_offset is 0, then the last section is not neccesarily
+ // full. If section_split_offset is not 0, then each section has two parts:
+ // bytes: [0..section_split_offset-1][section_split_offset..BufSize-1]
// pixels: [a..b][0..a-1]
// I.e. these two parts need to be swapped around.
- uint32 load_flags;
+ uint32 section_split_offset;
+
+ struct Block {
+ ByteStream bs;
+ iPoint2D beginCoord;
+ // The rectangle is an incorrect representation. All the rows
+ // between the first and last one span the entire width of the image.
+ iPoint2D endCoord;
+
+ Block() = default;
+ Block(ByteStream&& bs_, iPoint2D beginCoord_, iPoint2D endCoord_)
+ : bs(std::move(bs_)), beginCoord(beginCoord_), endCoord(endCoord_) {}
+ };
+
+ // If really wanted, this vector could be avoided,
+ // and each Block computed on-the-fly
+ std::vector<Block> blocks;
+
+ void chopInputIntoBlocks();
+
+ void processPixelPacket(ProxyStream* bits, int y, ushort16* dest, int xbegin,
+ std::vector<uint32>* zero_pos) const;
+
+ void processBlock(const Block& block, std::vector<uint32>* zero_pos) const;
+
+ void decompressThreaded(const RawDecompressorThread* t) const final;
public:
PanasonicDecompressor(const RawImage& img, const ByteStream& input_,
- bool zero_is_not_bad, uint32 load_flags_);
+ bool zero_is_not_bad, uint32 section_split_offset_);
+
+ void decompress() const final;
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.cpp b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.cpp
new file mode 100644
index 000000000..a1518a545
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.cpp
@@ -0,0 +1,255 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2018 Alexey Danilchenko
+ Copyright (C) 2018 Stefan Hoffmeister
+ 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 "decompressors/PanasonicDecompressorV5.h"
+#include "common/Point.h" // for iPoint2D
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "io/BitPumpLSB.h" // for BitPumpLSB
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include <algorithm> // for generate_n
+#include <cassert> // for assert
+#include <iterator> // for back_insert_iterator, back...
+#include <memory> // for allocator_traits<>::value_...
+#include <utility> // for move
+#include <vector> // for vector
+
+namespace rawspeed {
+
+struct PanasonicDecompressorV5::PacketDsc {
+ int bps;
+ int pixelsPerPacket;
+
+ constexpr PacketDsc();
+ explicit constexpr PacketDsc(int bps_)
+ : bps(bps_),
+ pixelsPerPacket(PanasonicDecompressorV5::bitsPerPacket / bps) {
+ // NOTE: the division is truncating. There may be some padding bits left.
+ }
+};
+
+constexpr PanasonicDecompressorV5::PacketDsc
+ PanasonicDecompressorV5::TwelveBitPacket =
+ PanasonicDecompressorV5::PacketDsc(/*bps=*/12);
+constexpr PanasonicDecompressorV5::PacketDsc
+ PanasonicDecompressorV5::FourteenBitPacket =
+ PanasonicDecompressorV5::PacketDsc(/*bps=*/14);
+
+PanasonicDecompressorV5::PanasonicDecompressorV5(const RawImage& img,
+ const ByteStream& input_,
+ uint32 bps_)
+ : AbstractParallelizedDecompressor(img), bps(bps_) {
+ if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
+ mRaw->getBpp() != 2)
+ ThrowRDE("Unexpected component count / data type");
+
+ const PacketDsc* dsc = nullptr;
+ switch (bps) {
+ case 12:
+ dsc = &TwelveBitPacket;
+ break;
+ case 14:
+ dsc = &FourteenBitPacket;
+ break;
+ default:
+ ThrowRDE("Unsupported bps: %u", bps);
+ }
+
+ if (!mRaw->dim.hasPositiveArea() || mRaw->dim.x % dsc->pixelsPerPacket != 0) {
+ ThrowRDE("Unexpected image dimensions found: (%i; %i)", mRaw->dim.x,
+ mRaw->dim.y);
+ }
+
+ // How many pixel packets does the specified pixel count require?
+ assert(mRaw->dim.area() % dsc->pixelsPerPacket == 0);
+ const auto numPackets = mRaw->dim.area() / dsc->pixelsPerPacket;
+ assert(numPackets > 0);
+
+ // And how many blocks that would be? Last block may not be full, pad it.
+ numBlocks = roundUpDivision(numPackets, PacketsPerBlock);
+ assert(numBlocks > 0);
+
+ // How many full blocks does the input contain? This is truncating division.
+ const auto haveBlocks = input_.getRemainSize() / BlockSize;
+
+ // Does the input contain enough blocks?
+ if (haveBlocks < numBlocks)
+ ThrowRDE("Unsufficient count of input blocks for a given image");
+
+ // We only want those blocks we need, no extras.
+ input = input_.peekStream(numBlocks, BlockSize);
+
+ chopInputIntoBlocks(*dsc);
+}
+
+void PanasonicDecompressorV5::chopInputIntoBlocks(const PacketDsc& dsc) {
+ auto pixelToCoordinate = [width = mRaw->dim.x](unsigned pixel) -> iPoint2D {
+ return iPoint2D(pixel % width, pixel / width);
+ };
+
+ assert(numBlocks * BlockSize == input.getRemainSize());
+ blocks.reserve(numBlocks);
+
+ const auto pixelsPerBlock = dsc.pixelsPerPacket * PacketsPerBlock;
+ assert((numBlocks - 1U) * pixelsPerBlock < mRaw->dim.area());
+ assert(numBlocks * pixelsPerBlock >= mRaw->dim.area());
+
+ unsigned currPixel = 0;
+ std::generate_n(std::back_inserter(blocks), numBlocks,
+ [input = &input, &currPixel, pixelToCoordinate,
+ pixelsPerBlock]() -> Block {
+ ByteStream bs = input->getStream(BlockSize);
+ iPoint2D beginCoord = pixelToCoordinate(currPixel);
+ currPixel += pixelsPerBlock;
+ iPoint2D endCoord = pixelToCoordinate(currPixel);
+ return {std::move(bs), beginCoord, endCoord};
+ });
+ assert(blocks.size() == numBlocks);
+ assert(currPixel >= mRaw->dim.area());
+ assert(input.getRemainSize() == 0);
+
+ // Clamp the end coordinate for the last block.
+ blocks.back().endCoord = mRaw->dim;
+ blocks.back().endCoord.y -= 1;
+}
+
+class PanasonicDecompressorV5::ProxyStream {
+ ByteStream block;
+ std::vector<uchar8> buf;
+ ByteStream input;
+
+ void parseBlock() {
+ assert(buf.empty());
+ assert(block.getRemainSize() == BlockSize);
+
+ static_assert(BlockSize > sectionSplitOffset, "");
+
+ Buffer FirstSection = block.getBuffer(sectionSplitOffset);
+ Buffer SecondSection = block.getBuffer(block.getRemainSize());
+ assert(FirstSection.getSize() < SecondSection.getSize());
+
+ buf.reserve(BlockSize);
+
+ // First copy the second section. This makes it the first section.
+ buf.insert(buf.end(), SecondSection.begin(), SecondSection.end());
+ // Now append the original 1'st section right after the new 1'st section.
+ buf.insert(buf.end(), FirstSection.begin(), FirstSection.end());
+
+ assert(buf.size() == BlockSize);
+ assert(block.getRemainSize() == 0);
+
+ // And reset the clock.
+ input = ByteStream(DataBuffer(Buffer(buf.data(), buf.size())));
+ // input.setByteOrder(Endianness::big); // does not seem to matter?!
+ }
+
+public:
+ explicit ProxyStream(ByteStream block_) : block(std::move(block_)) {}
+
+ ByteStream& getStream() {
+ parseBlock();
+ return input;
+ }
+};
+
+template <const PanasonicDecompressorV5::PacketDsc& dsc>
+void PanasonicDecompressorV5::processPixelPacket(BitPumpLSB* bs,
+ ushort16* dest) const {
+ static_assert(dsc.pixelsPerPacket > 0, "dsc should be compile-time const");
+ static_assert(dsc.bps > 0 && dsc.bps <= 16, "");
+
+ assert(bs->getFillLevel() == 0);
+
+ const ushort16* const endDest = dest + dsc.pixelsPerPacket;
+ for (; dest != endDest;) {
+ bs->fill();
+ for (; bs->getFillLevel() >= dsc.bps; dest++) {
+ assert(dest != endDest);
+
+ *dest = bs->getBitsNoFill(dsc.bps);
+ }
+ }
+ bs->skipBitsNoFill(bs->getFillLevel()); // get rid of padding.
+}
+
+template <const PanasonicDecompressorV5::PacketDsc& dsc>
+void PanasonicDecompressorV5::processBlock(const Block& block) const {
+ static_assert(dsc.pixelsPerPacket > 0, "dsc should be compile-time const");
+ static_assert(BlockSize % bytesPerPacket == 0, "");
+
+ ProxyStream proxy(block.bs);
+ BitPumpLSB bs(proxy.getStream());
+
+ for (int y = block.beginCoord.y; y <= block.endCoord.y; y++) {
+ int x = 0;
+ // First row may not begin at the first column.
+ if (block.beginCoord.y == y)
+ x = block.beginCoord.x;
+
+ int endx = mRaw->dim.x;
+ // Last row may end before the last column.
+ if (block.endCoord.y == y)
+ endx = block.endCoord.x;
+
+ auto* dest = reinterpret_cast<ushort16*>(mRaw->getData(x, y));
+
+ assert(x % dsc.pixelsPerPacket == 0);
+ assert(endx % dsc.pixelsPerPacket == 0);
+
+ for (; x < endx;) {
+ processPixelPacket<dsc>(&bs, dest);
+
+ x += dsc.pixelsPerPacket;
+ dest += dsc.pixelsPerPacket;
+ }
+ }
+}
+
+template <const PanasonicDecompressorV5::PacketDsc& dsc>
+void PanasonicDecompressorV5::decompressThreadedInternal(
+ const RawDecompressorThread* t) const {
+ assert(t->start < t->end);
+ assert(t->end <= blocks.size());
+ for (size_t i = t->start; i < t->end; i++)
+ processBlock<dsc>(blocks[i]);
+}
+
+void PanasonicDecompressorV5::decompressThreaded(
+ const RawDecompressorThread* t) const {
+ switch (bps) {
+ case 12:
+ decompressThreadedInternal<TwelveBitPacket>(t);
+ break;
+ case 14:
+ decompressThreadedInternal<FourteenBitPacket>(t);
+ break;
+ default:
+ __builtin_unreachable();
+ }
+}
+
+void PanasonicDecompressorV5::decompress() const {
+ assert(blocks.size() == numBlocks);
+ startThreading(blocks.size());
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.h b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.h
new file mode 100644
index 000000000..2af005cba
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PanasonicDecompressorV5.h
@@ -0,0 +1,109 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2018 Roman Lebedev
+ Copyright (C) 2018 Stefan Hoffmeister
+
+ 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
+*/
+
+#pragma once
+
+#include "common/Common.h" // for uint32
+#include "common/Point.h" // for iPoint2D
+#include "decompressors/AbstractParallelizedDecompressor.h"
+#include "io/BitPumpLSB.h" // for BitPumpLSB
+#include "io/ByteStream.h" // for ByteStream
+#include <cstddef> // for size_t
+#include <utility> // for move
+#include <vector> // for vector
+
+namespace rawspeed {
+
+class RawImage;
+
+class PanasonicDecompressorV5 final : public AbstractParallelizedDecompressor {
+ // The RW2 raw image buffer consists of individual blocks,
+ // each one BlockSize bytes in size.
+ static constexpr uint32 BlockSize = 0x4000;
+
+ // These blocks themselves comprise of two sections,
+ // split and swapped at section_split_offset:
+ // bytes: [0..sectionSplitOffset-1][sectionSplitOffset..BlockSize-1]
+ // pixels: [a..b][0..a-1]
+ // When reading, these two sections need to be swapped to enable linear
+ // processing..
+ static constexpr uint32 sectionSplitOffset = 0x1FF8;
+
+ // The blocks themselves consist of packets with fixed size of bytesPerPacket,
+ // and each packet decodes to pixelsPerPacket pixels, which depends on bps.
+ static constexpr uint32 bytesPerPacket = 16;
+ static constexpr uint32 bitsPerPacket = 8 * bytesPerPacket;
+ static_assert(BlockSize % bytesPerPacket == 0, "");
+ static constexpr uint32 PacketsPerBlock = BlockSize / bytesPerPacket;
+
+ // Contains the decoding recepie for the packet,
+ struct PacketDsc;
+
+ // There are two variants. Which one is to be used depends on image's bps.
+ static const PacketDsc TwelveBitPacket;
+ static const PacketDsc FourteenBitPacket;
+
+ // Takes care of unsplitting&swapping back the block at sectionSplitOffset.
+ class ProxyStream;
+
+ // The full input buffer, containing all the blocks.
+ ByteStream input;
+
+ const uint32 bps;
+
+ size_t numBlocks;
+
+ struct Block {
+ ByteStream bs;
+ iPoint2D beginCoord;
+ // The rectangle is an incorrect representation. All the rows
+ // between the first and last one span the entire width of the image.
+ iPoint2D endCoord;
+
+ Block() = default;
+ Block(ByteStream&& bs_, iPoint2D beginCoord_, iPoint2D endCoord_)
+ : bs(std::move(bs_)), beginCoord(beginCoord_), endCoord(endCoord_) {}
+ };
+
+ // If really wanted, this vector could be avoided,
+ // and each Block computed on-the-fly
+ std::vector<Block> blocks;
+
+ void chopInputIntoBlocks(const PacketDsc& dsc);
+
+ template <const PacketDsc& dsc>
+ void processPixelPacket(BitPumpLSB* bs, ushort16* dest) const;
+
+ template <const PacketDsc& dsc> void processBlock(const Block& block) const;
+
+ template <const PacketDsc& dsc>
+ void decompressThreadedInternal(const RawDecompressorThread* t) const;
+
+ void decompressThreaded(const RawDecompressorThread* t) const final;
+
+public:
+ PanasonicDecompressorV5(const RawImage& img, const ByteStream& input_,
+ uint32 bps_);
+
+ void decompress() const final;
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.cpp
index 50fff52ef..ef4a38241 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.cpp
@@ -27,20 +27,18 @@
#include "io/BitPumpMSB.h" // for BitPumpMSB, BitStream<>::f...
#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "tiff/TiffEntry.h" // for TiffEntry, ::TIFF_UNDEFINED
-#include "tiff/TiffIFD.h" // for TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag
#include <cassert> // for assert
-#include <vector> // for vector, allocator
+#include <vector> // for vector
namespace rawspeed {
// 16 entries of codes per bit length
// 13 entries of code values
-const uchar8 PentaxDecompressor::pentax_tree[][2][16] = {
- {{0, 2, 3, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
- {3, 4, 2, 5, 1, 6, 0, 7, 8, 9, 10, 11, 12}},
-};
+const std::array<std::array<std::array<uchar8, 16>, 2>, 1>
+ PentaxDecompressor::pentax_tree = {{
+ {{{0, 2, 3, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ {3, 4, 2, 5, 1, 6, 0, 7, 8, 9, 10, 11, 12}}},
+ }};
PentaxDecompressor::PentaxDecompressor(const RawImage& img,
ByteStream* metaData)
@@ -60,9 +58,9 @@ HuffmanTable PentaxDecompressor::SetupHuffmanTable_Legacy() {
HuffmanTable ht;
/* Initialize with legacy data */
- auto nCodes = ht.setNCodesPerLength(Buffer(pentax_tree[0][0], 16));
+ auto nCodes = ht.setNCodesPerLength(Buffer(pentax_tree[0][0].data(), 16));
assert(nCodes == 13); // see pentax_tree definition
- ht.setCodeValues(Buffer(pentax_tree[0][1], nCodes));
+ ht.setCodeValues(Buffer(pentax_tree[0][1].data(), nCodes));
return ht;
}
@@ -76,8 +74,8 @@ HuffmanTable PentaxDecompressor::SetupHuffmanTable_Modern(ByteStream stream) {
stream.skipBytes(12);
- uint32 v0[16];
- uint32 v1[16];
+ std::array<uint32, 16> v0;
+ std::array<uint32, 16> v1;
for (uint32 i = 0; i < depth; i++)
v0[i] = stream.getU16();
for (uint32 i = 0; i < depth; i++) {
@@ -90,7 +88,7 @@ HuffmanTable PentaxDecompressor::SetupHuffmanTable_Modern(ByteStream stream) {
std::vector<uchar8> nCodesPerLength;
nCodesPerLength.resize(17);
- uint32 v2[16];
+ std::array<uint32, 16> v2;
/* Calculate codes and store bitcounts */
for (uint32 c = 0; c < depth; c++) {
v2[c] = v0[c] >> (12 - v1[c]);
@@ -146,8 +144,8 @@ void PentaxDecompressor::decompress(const ByteStream& data) const {
assert(mRaw->dim.x > 0);
assert(mRaw->dim.x % 2 == 0);
- int pUp1[2] = {0, 0};
- int pUp2[2] = {0, 0};
+ std::array<int, 2> pUp1 = {{}};
+ std::array<int, 2> pUp2 = {{}};
for (int y = 0; y < mRaw->dim.y && mRaw->dim.x >= 2; y++) {
auto* dest = reinterpret_cast<ushort16*>(&draw[y * mRaw->pitch]);
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.h
index 76c5b84b3..4cc915977 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PentaxDecompressor.h
@@ -21,8 +21,8 @@
#pragma once
-#include "common/Common.h" // for uint32
-#include "common/RawImage.h" // for RawImage, RawImageData
+#include "common/Common.h" // for uchar8
+#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
#include "decompressors/HuffmanTable.h" // for HuffmanTable
@@ -30,8 +30,6 @@ namespace rawspeed {
class ByteStream;
-class TiffIFD;
-
class PentaxDecompressor final : public AbstractDecompressor {
RawImage mRaw;
const HuffmanTable ht;
@@ -46,7 +44,7 @@ private:
static HuffmanTable SetupHuffmanTable_Modern(ByteStream stream);
static HuffmanTable SetupHuffmanTable(ByteStream* metaData);
- static const uchar8 pentax_tree[][2][16];
+ static const std::array<std::array<std::array<uchar8, 16>, 2>, 1> pentax_tree;
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.cpp
new file mode 100644
index 000000000..61a733793
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.cpp
@@ -0,0 +1,152 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2009-2014 Klaus Post
+ Copyright (C) 2014-2015 Pedro Côrte-Real
+ Copyright (C) 2017-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 "decompressors/PhaseOneDecompressor.h"
+#include "common/Common.h" // for int32, uint32, ushort16
+#include "common/Point.h" // for iPoint2D
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "io/BitPumpMSB32.h" // for BitPumpMSB32
+#include <algorithm> // for for_each
+#include <array> // for array
+#include <cassert> // for assert
+#include <cstddef> // for size_t
+#include <utility> // for move
+#include <vector> // for vector, vector<>::size_type
+
+namespace rawspeed {
+
+PhaseOneDecompressor::PhaseOneDecompressor(const RawImage& img,
+ std::vector<PhaseOneStrip>&& strips_)
+ : AbstractParallelizedDecompressor(img), strips(std::move(strips_)) {
+ if (mRaw->getDataType() != TYPE_USHORT16)
+ ThrowRDE("Unexpected data type");
+
+ if (!((mRaw->getCpp() == 1 && mRaw->getBpp() == 2)))
+ ThrowRDE("Unexpected cpp: %u", mRaw->getCpp());
+
+ if (!mRaw->dim.hasPositiveArea() || mRaw->dim.x % 2 != 0 ||
+ mRaw->dim.x > 11608 || mRaw->dim.y > 8708) {
+ ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x,
+ mRaw->dim.y);
+ }
+
+ validateStrips();
+}
+
+void PhaseOneDecompressor::validateStrips() const {
+ // The 'strips' vector should contain exactly one element per row of image.
+
+ // If the lenght is different, then the 'strips' vector is clearly incorrect.
+ if (strips.size() != static_cast<decltype(strips)::size_type>(mRaw->dim.y)) {
+ ThrowRDE("Height (%u) vs strip count %zu mismatch", mRaw->dim.y,
+ strips.size());
+ }
+
+ struct RowBin {
+ using value_type = unsigned char;
+ bool isEmpty() const { return data == 0; }
+ void fill() { data = 1; }
+ value_type data = 0;
+ };
+
+ // Now, the strips in 'strips' vector aren't in order.
+ // The 'decltype(strips)::value_type::n' is the row number of a strip.
+ // We need to make sure that we have every row (0..mRaw->dim.y-1), once.
+
+ // There are many ways to do that. Here, we take the histogram of all the
+ // row numbers, and if any bin ends up not being '1' (one strip per row),
+ // then the input is bad.
+ std::vector<RowBin> histogram;
+ histogram.resize(strips.size());
+ int numBinsFilled = 0;
+ std::for_each(strips.begin(), strips.end(),
+ [y = mRaw->dim.y, &histogram,
+ &numBinsFilled](const PhaseOneStrip& strip) {
+ if (strip.n < 0 || strip.n >= y)
+ ThrowRDE("Strip specifies out-of-bounds row %u", strip.n);
+ RowBin& rowBin = histogram[strip.n];
+ if (!rowBin.isEmpty())
+ ThrowRDE("Duplicate row %u", strip.n);
+ rowBin.fill();
+ numBinsFilled++;
+ });
+ assert(histogram.size() == strips.size());
+ assert(numBinsFilled == mRaw->dim.y &&
+ "We should only get here if all the rows/bins got filled.");
+}
+
+void PhaseOneDecompressor::decompressStrip(const PhaseOneStrip& strip) const {
+ uint32 width = mRaw->dim.x;
+ assert(width % 2 == 0);
+
+ static constexpr std::array<const int, 10> length = {8, 7, 6, 9, 11,
+ 10, 5, 12, 14, 13};
+
+ BitPumpMSB32 pump(strip.bs);
+
+ std::array<int32, 2> pred;
+ pred.fill(0);
+ std::array<int, 2> len;
+ auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, strip.n));
+ for (uint32 col = 0; col < width; col++) {
+ if (col >= (width & ~7U)) // last 'width % 8' pixels.
+ len[0] = len[1] = 14;
+ else if ((col & 7) == 0) {
+ for (int& i : len) {
+ int j = 0;
+
+ for (; j < 5; j++) {
+ if (pump.getBits(1) != 0) {
+ if (col == 0)
+ ThrowRDE("Can not initialize lengths. Data is corrupt.");
+
+ // else, we have previously initialized lengths, so we are fine
+ break;
+ }
+ }
+
+ assert((col == 0 && j > 0) || col != 0);
+ if (j > 0)
+ i = length[2 * (j - 1) + pump.getBits(1)];
+ }
+ }
+
+ int i = len[col & 1];
+ if (i == 14)
+ img[col] = pred[col & 1] = pump.getBits(16);
+ else {
+ pred[col & 1] +=
+ static_cast<signed>(pump.getBits(i)) + 1 - (1 << (i - 1));
+ // FIXME: is the truncation the right solution here?
+ img[col] = ushort16(pred[col & 1]);
+ }
+ }
+}
+
+void PhaseOneDecompressor::decompressThreaded(
+ const RawDecompressorThread* t) const {
+ for (size_t i = t->start; i < t->end && i < strips.size(); i++)
+ decompressStrip(strips[i]);
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.h
new file mode 100644
index 000000000..e7b9d3f81
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/PhaseOneDecompressor.h
@@ -0,0 +1,55 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2009-2014 Klaus Post
+ Copyright (C) 2014 Pedro Côrte-Real
+ 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
+*/
+
+#pragma once
+
+#include "decompressors/AbstractParallelizedDecompressor.h" // for Abstract...
+#include "io/ByteStream.h" // for ByteStream
+#include <utility> // for move
+#include <vector> // for vector
+
+namespace rawspeed {
+
+class RawImage;
+
+struct PhaseOneStrip {
+ const int n;
+ const ByteStream bs;
+
+ PhaseOneStrip(int block, ByteStream bs_) : n(block), bs(std::move(bs_)) {}
+};
+
+class PhaseOneDecompressor final : public AbstractParallelizedDecompressor {
+ std::vector<PhaseOneStrip> strips;
+
+ void decompressStrip(const PhaseOneStrip& strip) const;
+
+ void decompressThreaded(const RawDecompressorThread* t) const final;
+
+ void validateStrips() const;
+
+public:
+ PhaseOneDecompressor(const RawImage& img,
+ std::vector<PhaseOneStrip>&& strips_);
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.cpp
index da31936bb..b67659580 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.cpp
@@ -21,17 +21,12 @@
*/
#include "decompressors/SamsungV0Decompressor.h"
-#include "common/Common.h" // for ushort16, uint32, int32
+#include "common/Common.h" // for uint32, ushort16, int32
#include "common/Point.h" // for iPoint2D
#include "common/RawImage.h" // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h" // for BitPumpMSB32
-#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for Endianness, Endianness::li...
-#include "tiff/TiffEntry.h" // for TiffEntry
-#include "tiff/TiffIFD.h" // for TiffIFD
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag::IMAGELENGTH
#include <algorithm> // for max
#include <cassert> // for assert
#include <iterator> // for advance, begin, end, next
@@ -122,7 +117,7 @@ void SamsungV0Decompressor::decompressStrip(uint32 y,
BitPumpMSB32 bits(bs);
- int len[4];
+ std::array<int, 4> len;
for (int& i : len)
i = y < 2 ? 7 : 4;
@@ -139,7 +134,7 @@ void SamsungV0Decompressor::decompressStrip(uint32 y,
bits.fill();
bool dir = !!bits.getBitsNoFill(1);
- int op[4];
+ std::array<int, 4> op;
for (int& i : op)
i = bits.getBitsNoFill(2);
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.h
index da840ee7b..958123c1d 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV0Decompressor.h
@@ -28,9 +28,7 @@
namespace rawspeed {
-class Buffer;
class RawImage;
-class TiffIFD;
// Decoder for compressed srw files (NX300 and later)
class SamsungV0Decompressor final : public AbstractSamsungDecompressor {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV1Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV1Decompressor.cpp
index 47e4fa285..a1aa17904 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV1Decompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV1Decompressor.cpp
@@ -84,12 +84,23 @@ void SamsungV1Decompressor::decompress() {
// encode, the second the number of bits that come after with the difference
// The table has 14 entries because the difference can have between 0 (no
// difference) and 13 bits (differences between 12 bits numbers can need 13)
- const uchar8 tab[14][2] = {{3, 4}, {3, 7}, {2, 6}, {2, 5}, {4, 3},
- {6, 0}, {7, 9}, {8, 10}, {9, 11}, {10, 12},
- {10, 13}, {5, 1}, {4, 8}, {4, 2}};
+ static const std::array<std::array<uchar8, 2>, 14> tab = {{{3, 4},
+ {3, 7},
+ {2, 6},
+ {2, 5},
+ {4, 3},
+ {6, 0},
+ {7, 9},
+ {8, 10},
+ {9, 11},
+ {10, 12},
+ {10, 13},
+ {5, 1},
+ {4, 8},
+ {4, 2}}};
std::vector<encTableItem> tbl(1024);
- ushort16 vpred[2][2] = {{0, 0}, {0, 0}};
- ushort16 hpred[2];
+ std::array<std::array<ushort16, 2>, 2> vpred = {{}};
+ std::array<ushort16, 2> hpred;
// We generate a 1024 entry table (to be addressed by reading 10 bits) by
// consecutively filling in 2^(10-N) positions where N is the variable number
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV2Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV2Decompressor.cpp
index 49b3a33e3..b3f71c922 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SamsungV2Decompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SamsungV2Decompressor.cpp
@@ -202,7 +202,7 @@ void SamsungV2Decompressor::decompressRow(uint32 row) {
// By default we are not scaling values at all
int32 scale = 0;
- uint32 diffBitsMode[3][2] = {{0}};
+ std::array<std::array<int, 2>, 3> diffBitsMode = {{}};
for (auto& i : diffBitsMode)
i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;
@@ -210,7 +210,7 @@ void SamsungV2Decompressor::decompressRow(uint32 row) {
assert(width % 16 == 0);
for (uint32 col = 0; col < width; col += 16) {
if (!(optflags & OptFlags::QP) && !(col & 63)) {
- static constexpr int32 scalevals[] = {0, -2, 2};
+ static constexpr std::array<int32, 3> scalevals = {{0, -2, 2}};
uint32 i = pump.getBits(2);
scale = i < 3 ? scale + scalevals[i] : pump.getBits(12);
}
@@ -236,8 +236,10 @@ void SamsungV2Decompressor::decompressRow(uint32 row) {
ThrowRDE(
"Got a previous line lookup on first two lines. File corrupted?");
- static constexpr int32 motionOffset[7] = {-4, -2, -2, 0, 0, 2, 4};
- static constexpr int32 motionDoAverage[7] = {0, 0, 1, 0, 1, 0, 0};
+ static constexpr std::array<int32, 7> motionOffset = {-4, -2, -2, 0,
+ 0, 2, 4};
+ static constexpr std::array<int32, 7> motionDoAverage = {0, 0, 1, 0,
+ 1, 0, 0};
int32 slideOffset = motionOffset[motion];
int32 doAverage = motionDoAverage[motion];
@@ -273,9 +275,9 @@ void SamsungV2Decompressor::decompressRow(uint32 row) {
}
// Figure out how many difference bits we have to read for each pixel
- uint32 diffBits[4] = {0};
+ std::array<uint32, 4> diffBits = {};
if (optflags & OptFlags::SKIP || !pump.getBits(1)) {
- uint32 flags[4];
+ std::array<uint32, 4> flags;
for (unsigned int& flag : flags)
flag = pump.getBits(2);
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.cpp
index 0d6bddc30..1cbd2360b 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.cpp
@@ -21,14 +21,13 @@
*/
#include "decompressors/SonyArw1Decompressor.h"
-#include "common/Common.h" // for uchar8
-#include "common/Point.h" // for iPoint2D
-#include "common/RawImage.h" // for RawImage
-#include "decoders/RawDecoderException.h" // for ThrowRDE
-#include "decompressors/AbstractDecompressor.h" // for RawDecom...
-#include "decompressors/HuffmanTable.h" // for HuffmanTable
-#include "io/BitPumpMSB.h" // for BitPumpMSB
-#include <algorithm> // for move
+#include "common/Common.h" // for uint32, uchar8, ushort16
+#include "common/Point.h" // for iPoint2D
+#include "common/RawImage.h" // for RawImage, RawImageData
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "decompressors/HuffmanTable.h" // for HuffmanTable
+#include "io/BitPumpMSB.h" // for BitPumpMSB
+#include <cassert> // for assert
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.h
index 67a158675..1be0ccb8a 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SonyArw1Decompressor.h
@@ -22,11 +22,10 @@
#include "common/RawImage.h" // for RawImage
#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
-#include "io/ByteStream.h" // for ByteStream
namespace rawspeed {
-class RawImage;
+class ByteStream;
class SonyArw1Decompressor final : public AbstractDecompressor {
RawImage mRaw;
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/SonyArw2Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/SonyArw2Decompressor.cpp
index 231b23a72..8465ed013 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/SonyArw2Decompressor.cpp
+++ b/src/external/rawspeed/src/librawspeed/decompressors/SonyArw2Decompressor.cpp
@@ -21,13 +21,13 @@
*/
#include "decompressors/SonyArw2Decompressor.h"
-#include "common/Common.h" // for uchar8
+#include "common/Common.h" // for uint32
#include "common/Point.h" // for iPoint2D
#include "common/RawImage.h" // for RawImage
-#include "decoders/RawDecoderException.h" // for ThrowRDE, ...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "decompressors/AbstractParallelizedDecompressor.h" // for RawDecom...
#include "io/BitPumpLSB.h" // for BitPumpLSB
-#include <algorithm> // for move
+#include <cassert> // for assert
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/UncompressedDecompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/UncompressedDecompressor.h
index 6e625137c..8d70c19a3 100644
--- a/src/external/rawspeed/src/librawspeed/decompressors/UncompressedDecompressor.h
+++ b/src/external/rawspeed/src/librawspeed/decompressors/UncompressedDecompressor.h
@@ -28,7 +28,7 @@
#include "io/Buffer.h" // for Buffer, Buffer::size_type
#include "io/ByteStream.h" // for ByteStream
#include "io/Endianness.h" // for Endianness
-#include <algorithm> // for move
+#include <utility> // for move
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.cpp b/src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.cpp
new file mode 100644
index 000000000..b6ffde7bc
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.cpp
@@ -0,0 +1,829 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2018 Stefan Löffler
+ 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
+*/
+
+/*
+ This is a decompressor for VC-5 raw compression algo, as used in GoPro raws.
+ This implementation is similar to that one of the official reference
+ implementation of the https://github.com/gopro/gpr project, and is producing
+ bitwise-identical output as compared with the Adobe DNG Converter
+ implementation.
+ */
+
+#include "rawspeedconfig.h"
+#include "decompressors/VC5Decompressor.h"
+#include "common/Array2DRef.h" // for Array2DRef
+#include "common/Optional.h" // for Optional
+#include "common/Point.h" // for iPoint2D
+#include "common/RawspeedException.h" // for RawspeedException
+#include "common/SimpleLUT.h" // for SimpleLUT, SimpleLUT<>::va...
+#include "decoders/RawDecoderException.h" // for ThrowRDE
+#include "io/Endianness.h" // for Endianness, Endianness::big
+#include <cassert> // for assert
+#include <cmath> // for pow
+#include <initializer_list> // for initializer_list
+#include <limits> // for numeric_limits
+#include <string> // for string
+#include <utility> // for move
+
+namespace {
+
+// Definitions needed by table17.inc
+// Taken from
+// https://github.com/gopro/gpr/blob/a513701afce7b03173213a2f67dfd9dd28fa1868/source/lib/vc5_decoder/vlc.h
+struct RLV {
+ uint_fast8_t size; //!< Size of code word in bits
+ uint32_t bits; //!< Code word bits right justified
+ uint16_t count; //!< Run length
+ uint16_t value; //!< Run value (unsigned)
+};
+#define RLVTABLE(n) \
+ struct { \
+ const uint32_t length; \
+ const RLV entries[n]; \
+ } constexpr
+#include "gopro/vc5/table17.inc"
+
+constexpr int16_t decompand(int16_t val) {
+ double c = val;
+ // Invert companding curve
+ c += (c * c * c * 768) / (255. * 255. * 255.);
+ if (c > std::numeric_limits<int16_t>::max())
+ return std::numeric_limits<int16_t>::max();
+ if (c < std::numeric_limits<int16_t>::min())
+ return std::numeric_limits<int16_t>::min();
+ return c;
+}
+
+#ifndef NDEBUG
+int ignore = []() {
+ for (const RLV& entry : table17.entries) {
+ assert(((-decompand(entry.value)) == decompand(-int16_t(entry.value))) &&
+ "negation of decompanded value is the same as decompanding of "
+ "negated value");
+ }
+ return 0;
+}();
+#endif
+
+const std::array<RLV, table17.length> decompandedTable17 = []() {
+ std::array<RLV, table17.length> d;
+ for (auto i = 0U; i < table17.length; i++) {
+ d[i] = table17.entries[i];
+ d[i].value = decompand(table17.entries[i].value);
+ }
+ return d;
+}();
+
+} // namespace
+
+#define PRECISION_MIN 8
+#define PRECISION_MAX 32
+
+#define MARKER_BAND_END 1
+
+namespace rawspeed {
+
+void VC5Decompressor::Wavelet::setBandValid(const int band) {
+ mDecodedBandMask |= (1 << band);
+}
+
+bool VC5Decompressor::Wavelet::isBandValid(const int band) const {
+ return mDecodedBandMask & (1 << band);
+}
+
+bool VC5Decompressor::Wavelet::allBandsValid() const {
+ return mDecodedBandMask == static_cast<uint32>((1 << numBands) - 1);
+}
+
+Array2DRef<const int16_t>
+VC5Decompressor::Wavelet::bandAsArray2DRef(const unsigned int iBand) const {
+ return {bands[iBand]->data.data(), width, height};
+}
+
+namespace {
+auto convolute = [](int x, int y, std::array<int, 4> muls,
+ const Array2DRef<const int16_t> high, auto lowGetter,
+ int DescaleShift = 0) {
+ auto highCombined = muls[0] * high(x, y);
+ auto lowsCombined = [muls, lowGetter]() {
+ int lows = 0;
+ for (int i = 0; i < 3; i++)
+ lows += muls[1 + i] * lowGetter(i);
+ return lows;
+ }();
+ // Round up 'lows' up
+ lowsCombined += 4;
+ // And finally 'average' them.
+ auto lowsRounded = lowsCombined >> 3;
+ auto total = highCombined + lowsRounded;
+ // Descale it.
+ total <<= DescaleShift;
+ // And average it.
+ total >>= 1;
+ return total;
+};
+
+struct ConvolutionParams {
+ struct First {
+ static constexpr std::array<int, 4> mul_even = {+1, +11, -4, +1};
+ static constexpr std::array<int, 4> mul_odd = {-1, +5, +4, -1};
+ static constexpr int coord_shift = 0;
+ };
+ static constexpr First First{};
+
+ struct Middle {
+ static constexpr std::array<int, 4> mul_even = {+1, +1, +8, -1};
+ static constexpr std::array<int, 4> mul_odd = {-1, -1, +8, +1};
+ static constexpr int coord_shift = -1;
+ };
+ static constexpr Middle Middle{};
+
+ struct Last {
+ static constexpr std::array<int, 4> mul_even = {+1, -1, +4, +5};
+ static constexpr std::array<int, 4> mul_odd = {-1, +1, -4, +11};
+ static constexpr int coord_shift = -2;
+ };
+ static constexpr Last Last{};
+};
+
+constexpr std::array<int, 4> ConvolutionParams::First::mul_even;
+constexpr std::array<int, 4> ConvolutionParams::First::mul_odd;
+
+constexpr std::array<int, 4> ConvolutionParams::Middle::mul_even;
+constexpr std::array<int, 4> ConvolutionParams::Middle::mul_odd;
+
+constexpr std::array<int, 4> ConvolutionParams::Last::mul_even;
+constexpr std::array<int, 4> ConvolutionParams::Last::mul_odd;
+
+} // namespace
+
+void VC5Decompressor::Wavelet::reconstructPass(
+ const Array2DRef<int16_t> dst, const Array2DRef<const int16_t> high,
+ const Array2DRef<const int16_t> low) const noexcept {
+ auto process = [low, high, dst](auto segment, int x, int y) {
+ auto lowGetter = [&x, &y, low](int delta) {
+ return low(x, y + decltype(segment)::coord_shift + delta);
+ };
+ auto convolution = [&x, &y, high, lowGetter](std::array<int, 4> muls) {
+ return convolute(x, y, muls, high, lowGetter, /*DescaleShift*/ 0);
+ };
+
+ int even = convolution(decltype(segment)::mul_even);
+ int odd = convolution(decltype(segment)::mul_odd);
+
+ dst(x, 2 * y) = static_cast<int16_t>(even);
+ dst(x, 2 * y + 1) = static_cast<int16_t>(odd);
+ };
+
+ // Vertical reconstruction
+#ifdef HAVE_OPENMP
+#pragma omp for schedule(static)
+#endif
+ for (int y = 0; y < height; ++y) {
+ if (y == 0) {
+ // 1st row
+ for (int x = 0; x < width; ++x)
+ process(ConvolutionParams::First, x, y);
+ } else if (y + 1 < height) {
+ // middle rows
+ for (int x = 0; x < width; ++x)
+ process(ConvolutionParams::Middle, x, y);
+ } else {
+ // last row
+ for (int x = 0; x < width; ++x)
+ process(ConvolutionParams::Last, x, y);
+ }
+ }
+}
+
+void VC5Decompressor::Wavelet::combineLowHighPass(
+ const Array2DRef<int16_t> dst, const Array2DRef<const int16_t> low,
+ const Array2DRef<const int16_t> high, int descaleShift,
+ bool clampUint = false) const noexcept {
+ auto process = [low, high, descaleShift, clampUint, dst](auto segment, int x,
+ int y) {
+ auto lowGetter = [&x, &y, low](int delta) {
+ return low(x + decltype(segment)::coord_shift + delta, y);
+ };
+ auto convolution = [&x, &y, high, lowGetter,
+ descaleShift](std::array<int, 4> muls) {
+ return convolute(x, y, muls, high, lowGetter, descaleShift);
+ };
+
+ int even = convolution(decltype(segment)::mul_even);
+ int odd = convolution(decltype(segment)::mul_odd);
+
+ if (clampUint) {
+ even = clampBits(even, 14);
+ odd = clampBits(odd, 14);
+ }
+ dst(2 * x, y) = static_cast<int16_t>(even);
+ dst(2 * x + 1, y) = static_cast<int16_t>(odd);
+ };
+
+ // Horizontal reconstruction
+#ifdef HAVE_OPENMP
+#pragma omp for schedule(static)
+#endif
+ for (int y = 0; y < dst.height; ++y) {
+ // First col
+ int x = 0;
+ process(ConvolutionParams::First, x, y);
+ // middle cols
+ for (x = 1; x + 1 < width; ++x) {
+ process(ConvolutionParams::Middle, x, y);
+ }
+ // last col
+ process(ConvolutionParams::Last, x, y);
+ }
+}
+
+void VC5Decompressor::Wavelet::ReconstructableBand::processLow(
+ const Wavelet& wavelet) noexcept {
+ Array2DRef<int16_t> lowpass;
+#ifdef HAVE_OPENMP
+#pragma omp single copyprivate(lowpass)
+#endif
+ lowpass = Array2DRef<int16_t>::create(&lowpass_storage, wavelet.width,
+ 2 * wavelet.height);
+
+ const Array2DRef<const int16_t> highlow = wavelet.bandAsArray2DRef(2);
+ const Array2DRef<const int16_t> lowlow = wavelet.bandAsArray2DRef(0);
+
+ // Reconstruct the "immediates", the actual low pass ...
+ wavelet.reconstructPass(lowpass, highlow, lowlow);
+}
+
+void VC5Decompressor::Wavelet::ReconstructableBand::processHigh(
+ const Wavelet& wavelet) noexcept {
+ Array2DRef<int16_t> highpass;
+#ifdef HAVE_OPENMP
+#pragma omp single copyprivate(highpass)
+#endif
+ highpass = Array2DRef<int16_t>::create(&highpass_storage, wavelet.width,
+ 2 * wavelet.height);
+
+ const Array2DRef<const int16_t> highhigh = wavelet.bandAsArray2DRef(3);
+ const Array2DRef<const int16_t> lowhigh = wavelet.bandAsArray2DRef(1);
+
+ wavelet.reconstructPass(highpass, highhigh, lowhigh);
+}
+
+void VC5Decompressor::Wavelet::ReconstructableBand::combine(
+ const Wavelet& wavelet) noexcept {
+ int16_t descaleShift = (wavelet.prescale == 2 ? 2 : 0);
+
+ Array2DRef<int16_t> dest;
+#ifdef HAVE_OPENMP
+#pragma omp single copyprivate(dest)
+#endif
+ dest =
+ Array2DRef<int16_t>::create(&data, 2 * wavelet.width, 2 * wavelet.height);
+
+ const Array2DRef<int16_t> lowpass(lowpass_storage.data(), wavelet.width,
+ 2 * wavelet.height);
+ const Array2DRef<int16_t> highpass(highpass_storage.data(), wavelet.width,
+ 2 * wavelet.height);
+
+ // And finally, combine the low pass, and high pass.
+ wavelet.combineLowHighPass(dest, lowpass, highpass, descaleShift, clampUint);
+}
+
+void VC5Decompressor::Wavelet::ReconstructableBand::decode(
+ const Wavelet& wavelet) noexcept {
+ assert(wavelet.allBandsValid());
+ assert(data.empty());
+ processLow(wavelet);
+ processHigh(wavelet);
+ combine(wavelet);
+}
+
+VC5Decompressor::VC5Decompressor(ByteStream bs, const RawImage& img)
+ : mRaw(img), mBs(std::move(bs)) {
+ if (!mRaw->dim.hasPositiveArea())
+ ThrowRDE("Bad image dimensions.");
+
+ if (mRaw->dim.x % mVC5.patternWidth != 0)
+ ThrowRDE("Width %u is not a multiple of %u", mRaw->dim.x,
+ mVC5.patternWidth);
+
+ if (mRaw->dim.y % mVC5.patternHeight != 0)
+ ThrowRDE("Height %u is not a multiple of %u", mRaw->dim.y,
+ mVC5.patternHeight);
+
+ // Initialize wavelet sizes.
+ for (Channel& channel : channels) {
+ channel.width = mRaw->dim.x / mVC5.patternWidth;
+ channel.height = mRaw->dim.y / mVC5.patternHeight;
+
+ uint16_t waveletWidth = channel.width;
+ uint16_t waveletHeight = channel.height;
+ for (Wavelet& wavelet : channel.wavelets) {
+ // Pad dimensions as necessary and divide them by two for the next wavelet
+ for (auto* dimension : {&waveletWidth, &waveletHeight})
+ *dimension = roundUpDivision(*dimension, 2);
+ wavelet.width = waveletWidth;
+ wavelet.height = waveletHeight;
+ }
+ }
+
+ if (img->whitePoint <= 0 || img->whitePoint > int(((1U << 16U) - 1U)))
+ ThrowRDE("Bad white level %i", img->whitePoint);
+
+ outputBits = 0;
+ for (int wp = img->whitePoint; wp != 0; wp >>= 1)
+ ++outputBits;
+ assert(outputBits <= 16);
+
+ parseVC5();
+}
+
+void VC5Decompressor::initVC5LogTable() {
+ mVC5LogTable = decltype(mVC5LogTable)(
+ [outputBits = outputBits](unsigned i, unsigned tableSize) {
+ // The vanilla "inverse log" curve for decoding.
+ auto normalizedCurve = [](auto normalizedI) {
+ return (std::pow(113.0, normalizedI) - 1) / 112.0;
+ };
+
+ auto normalizeI = [tableSize](auto x) { return x / (tableSize - 1.0); };
+ auto denormalizeY = [maxVal = std::numeric_limits<ushort16>::max()](
+ auto y) { return maxVal * y; };
+ // Adjust for output whitelevel bitdepth.
+ auto rescaleY = [outputBits](auto y) {
+ auto scale = 16 - outputBits;
+ return y >> scale;
+ };
+
+ const auto naiveY = denormalizeY(normalizedCurve(normalizeI(i)));
+ const auto intY = static_cast<unsigned int>(naiveY);
+ const auto rescaledY = rescaleY(intY);
+ return rescaledY;
+ });
+}
+
+void VC5Decompressor::parseVC5() {
+ mBs.setByteOrder(Endianness::big);
+
+ assert(mRaw->dim.x > 0);
+ assert(mRaw->dim.y > 0);
+
+ // All VC-5 data must start with "VC-%" (0x56432d35)
+ if (mBs.getU32() != 0x56432d35)
+ ThrowRDE("not a valid VC-5 datablock");
+
+ bool done = false;
+ while (!done) {
+ auto tag = static_cast<VC5Tag>(mBs.getU16());
+ ushort16 val = mBs.getU16();
+
+ bool optional = matches(tag, VC5Tag::Optional);
+ if (optional)
+ tag = -tag;
+
+ switch (tag) {
+ case VC5Tag::ChannelCount:
+ if (val != numChannels)
+ ThrowRDE("Bad channel count %u, expected %u", val, numChannels);
+ break;
+ case VC5Tag::ImageWidth:
+ if (val != mRaw->dim.x)
+ ThrowRDE("Image width mismatch: %u vs %u", val, mRaw->dim.x);
+ break;
+ case VC5Tag::ImageHeight:
+ if (val != mRaw->dim.y)
+ ThrowRDE("Image height mismatch: %u vs %u", val, mRaw->dim.y);
+ break;
+ case VC5Tag::LowpassPrecision:
+ if (val < PRECISION_MIN || val > PRECISION_MAX)
+ ThrowRDE("Invalid precision %i", val);
+ mVC5.lowpassPrecision = val;
+ break;
+ case VC5Tag::ChannelNumber:
+ if (val >= numChannels)
+ ThrowRDE("Bad channel number (%u)", val);
+ mVC5.iChannel = val;
+ break;
+ case VC5Tag::ImageFormat:
+ if (val != mVC5.imgFormat)
+ ThrowRDE("Image format %i is not 4(RAW)", val);
+ break;
+ case VC5Tag::SubbandCount:
+ if (val != numSubbands)
+ ThrowRDE("Unexpected subband count %u, expected %u", val, numSubbands);
+ break;
+ case VC5Tag::MaxBitsPerComponent:
+ if (val != VC5_LOG_TABLE_BITWIDTH) {
+ ThrowRDE("Bad bits per componend %u, not %u", val,
+ VC5_LOG_TABLE_BITWIDTH);
+ }
+ break;
+ case VC5Tag::PatternWidth:
+ if (val != mVC5.patternWidth)
+ ThrowRDE("Bad pattern width %u, not %u", val, mVC5.patternWidth);
+ break;
+ case VC5Tag::PatternHeight:
+ if (val != mVC5.patternHeight)
+ ThrowRDE("Bad pattern height %u, not %u", val, mVC5.patternHeight);
+ break;
+ case VC5Tag::SubbandNumber:
+ if (val >= numSubbands)
+ ThrowRDE("Bad subband number %u", val);
+ mVC5.iSubband = val;
+ break;
+ case VC5Tag::Quantization:
+ mVC5.quantization = static_cast<short16>(val);
+ break;
+ case VC5Tag::ComponentsPerSample:
+ if (val != mVC5.cps)
+ ThrowRDE("Bad compnent per sample count %u, not %u", val, mVC5.cps);
+ break;
+ case VC5Tag::PrescaleShift:
+ // FIXME: something is wrong. We get this before VC5Tag::ChannelNumber.
+ // Defaulting to 'mVC5.iChannel=0' seems to work *for existing samples*.
+ for (int iWavelet = 0; iWavelet < numWaveletLevels; ++iWavelet) {
+ auto& channel = channels[mVC5.iChannel];
+ auto& wavelet = channel.wavelets[iWavelet];
+ wavelet.prescale = (val >> (14 - 2 * iWavelet)) & 0x03;
+ }
+ break;
+ default: { // A chunk.
+ unsigned int chunkSize = 0;
+ if (matches(tag, VC5Tag::LARGE_CHUNK)) {
+ chunkSize = static_cast<unsigned int>(
+ ((static_cast<std::underlying_type<VC5Tag>::type>(tag) & 0xff)
+ << 16) |
+ (val & 0xffff));
+ } else if (matches(tag, VC5Tag::SMALL_CHUNK)) {
+ chunkSize = (val & 0xffff);
+ }
+
+ if (is(tag, VC5Tag::LargeCodeblock)) {
+ parseLargeCodeblock(mBs.getStream(chunkSize, 4));
+ break;
+ }
+
+ // And finally, we got here if we didn't handle this tag/maybe-chunk.
+
+ // Magic, all the other 'large' chunks are actually optional,
+ // and don't specify any chunk bytes-to-be-skipped.
+ if (matches(tag, VC5Tag::LARGE_CHUNK)) {
+ optional = true;
+ chunkSize = 0;
+ }
+
+ if (!optional) {
+ ThrowRDE("Unknown (unhandled) non-optional Tag 0x%04hx",
+ static_cast<std::underlying_type<VC5Tag>::type>(tag));
+ }
+
+ if (chunkSize)
+ mBs.skipBytes(chunkSize, 4);
+
+ break;
+ }
+ }
+
+ done = true;
+ for (int iChannel = 0; iChannel < numChannels && done; ++iChannel) {
+ Wavelet& wavelet = channels[iChannel].wavelets[0];
+ if (!wavelet.allBandsValid())
+ done = false;
+ }
+ }
+}
+
+VC5Decompressor::Wavelet::LowPassBand::LowPassBand(const Wavelet& wavelet,
+ ByteStream bs_,
+ ushort16 lowpassPrecision_)
+ : AbstractDecodeableBand(std::move(bs_)),
+ lowpassPrecision(lowpassPrecision_) {
+ // Low-pass band is a uncompressed version of the image, hugely downscaled.
+ // It consists of width * height pixels, `lowpassPrecision` each.
+ // We can easily check that we have sufficient amount of bits to decode it.
+ const auto waveletArea = iPoint2D(wavelet.width, wavelet.height).area();
+ const auto bitsTotal = waveletArea * lowpassPrecision;
+ const auto bytesTotal = roundUpDivision(bitsTotal, 8);
+ bs = bs.getStream(bytesTotal); // And clamp the size while we are at it.
+}
+
+void VC5Decompressor::Wavelet::LowPassBand::decode(const Wavelet& wavelet) {
+ const auto dst =
+ Array2DRef<int16_t>::create(&data, wavelet.width, wavelet.height);
+
+ BitPumpMSB bits(bs);
+ for (auto row = 0; row < dst.height; ++row) {
+ for (auto col = 0; col < dst.width; ++col)
+ dst(col, row) = static_cast<int16_t>(bits.getBits(lowpassPrecision));
+ }
+}
+
+void VC5Decompressor::Wavelet::HighPassBand::decode(const Wavelet& wavelet) {
+ auto dequantize = [quant = quant](int16_t val) -> int16_t {
+ return val * quant;
+ };
+
+ Array2DRef<int16_t>::create(&data, wavelet.width, wavelet.height);
+
+ BitPumpMSB bits(bs);
+ // decode highpass band
+ int pixelValue = 0;
+ unsigned int count = 0;
+ int nPixels = wavelet.width * wavelet.height;
+ for (int iPixel = 0; iPixel < nPixels;) {
+ getRLV(&bits, &pixelValue, &count);
+ for (; count > 0; --count) {
+ if (iPixel >= nPixels)
+ ThrowRDE("Buffer overflow");
+ data[iPixel] = dequantize(pixelValue);
+ ++iPixel;
+ }
+ }
+ getRLV(&bits, &pixelValue, &count);
+ static_assert(decompand(MARKER_BAND_END) == MARKER_BAND_END, "passthrought");
+ if (pixelValue != MARKER_BAND_END || count != 0)
+ ThrowRDE("EndOfBand marker not found");
+}
+
+void VC5Decompressor::parseLargeCodeblock(const ByteStream& bs) {
+ static const auto subband_wavelet_index = []() {
+ std::array<int, numSubbands> wavelets;
+ int wavelet = 0;
+ for (auto i = wavelets.size() - 1; i > 0;) {
+ for (auto t = 0; t < numWaveletLevels; t++) {
+ wavelets[i] = wavelet;
+ i--;
+ }
+ if (i > 0)
+ wavelet++;
+ }
+ wavelets.front() = wavelet;
+ return wavelets;
+ }();
+ static const auto subband_band_index = []() {
+ std::array<int, numSubbands> bands;
+ bands.front() = 0;
+ for (auto i = 1U; i < bands.size();) {
+ for (int t = 1; t <= numWaveletLevels;) {
+ bands[i] = t;
+ t++;
+ i++;
+ }
+ }
+ return bands;
+ }();
+
+ if (!mVC5.iSubband.hasValue())
+ ThrowRDE("Did not see VC5Tag::SubbandNumber yet");
+
+ const int idx = subband_wavelet_index[mVC5.iSubband.getValue()];
+ const int band = subband_band_index[mVC5.iSubband.getValue()];
+
+ auto& wavelets = channels[mVC5.iChannel].wavelets;
+
+ Wavelet& wavelet = wavelets[idx];
+ if (wavelet.isBandValid(band)) {
+ ThrowRDE("Band %u for wavelet %u on channel %u was already seen", band, idx,
+ mVC5.iChannel);
+ }
+
+ std::unique_ptr<Wavelet::AbstractBand>& dstBand = wavelet.bands[band];
+ if (mVC5.iSubband.getValue() == 0) {
+ assert(band == 0);
+ // low-pass band, only one, for the smallest wavelet, per channel per image
+ if (!mVC5.lowpassPrecision.hasValue())
+ ThrowRDE("Did not see VC5Tag::LowpassPrecision yet");
+ dstBand = std::make_unique<Wavelet::LowPassBand>(
+ wavelet, bs, mVC5.lowpassPrecision.getValue());
+ mVC5.lowpassPrecision.reset();
+ } else {
+ if (!mVC5.quantization.hasValue())
+ ThrowRDE("Did not see VC5Tag::Quantization yet");
+ dstBand = std::make_unique<Wavelet::HighPassBand>(
+ bs, mVC5.quantization.getValue());
+ mVC5.quantization.reset();
+ }
+ wavelet.setBandValid(band);
+
+ // If this wavelet is fully specified, mark the low-pass band of the
+ // next lower wavelet as specified.
+ if (idx > 0 && wavelet.allBandsValid()) {
+ Wavelet& nextWavelet = wavelets[idx - 1];
+ assert(!nextWavelet.isBandValid(0));
+ nextWavelet.bands[0] = std::make_unique<Wavelet::ReconstructableBand>();
+ nextWavelet.setBandValid(0);
+ }
+
+ mVC5.iSubband.reset();
+}
+
+void VC5Decompressor::decode(unsigned int offsetX, unsigned int offsetY,
+ unsigned int width, unsigned int height) {
+ if (offsetX || offsetY || mRaw->dim != iPoint2D(width, height))
+ ThrowRDE("VC5Decompressor expects to fill the whole image, not some tile.");
+
+ initVC5LogTable();
+
+ const std::vector<DecodeableBand> allDecodeableBands = [&]() {
+ std::vector<DecodeableBand> bands;
+ bands.reserve(numSubbandsTotal);
+ // All the high-pass bands for all wavelets,
+ // in this specific order of decreasing worksize.
+ for (int waveletLevel = 0; waveletLevel < numWaveletLevels;
+ waveletLevel++) {
+ for (auto channelId = 0; channelId < numChannels; channelId++) {
+ for (int bandId = 1; bandId <= numHighPassBands; bandId++) {
+ auto& channel = channels[channelId];
+ auto& wavelet = channel.wavelets[waveletLevel];
+ auto* band = wavelet.bands[bandId].get();
+ auto* decodeableHighPassBand =
+ dynamic_cast<Wavelet::HighPassBand*>(band);
+ bands.emplace_back(decodeableHighPassBand, wavelet);
+ }
+ }
+ }
+ // The low-pass bands at the end. I'm guessing they should be fast to
+ // decode.
+ for (Channel& channel : channels) {
+ // Low-pass band of the smallest wavelet.
+ Wavelet& smallestWavelet = channel.wavelets.back();
+ auto* decodeableLowPassBand =
+ dynamic_cast<Wavelet::LowPassBand*>(smallestWavelet.bands[0].get());
+ bands.emplace_back(decodeableLowPassBand, smallestWavelet);
+ }
+ assert(allDecodeableBands.size() == numSubbandsTotal);
+ return bands;
+ }();
+
+ const std::vector<ReconstructionStep> reconstructionSteps = [&]() {
+ std::vector<ReconstructionStep> steps;
+ steps.reserve(numLowPassBandsTotal);
+ // For every channel, recursively reconstruct the low-pass bands.
+ for (auto& channel : channels) {
+ // Reconstruct the intermediate lowpass bands.
+ for (int waveletLevel = numWaveletLevels - 1; waveletLevel > 0;
+ waveletLevel--) {
+ Wavelet* wavelet = &(channel.wavelets[waveletLevel]);
+ Wavelet& nextWavelet = channel.wavelets[waveletLevel - 1];
+
+ auto* band = dynamic_cast<Wavelet::ReconstructableBand*>(
+ nextWavelet.bands[0].get());
+ steps.emplace_back(wavelet, band);
+ }
+ // Finally, reconstruct the final lowpass band.
+ Wavelet* wavelet = &(channel.wavelets.front());
+ steps.emplace_back(wavelet, &(channel.band));
+ }
+ assert(steps.size() == numLowPassBandsTotal);
+ return steps;
+ }();
+
+#ifdef HAVE_OPENMP
+ bool exceptionThrown = false;
+#pragma omp parallel default(none) shared(exceptionThrown) \
+ num_threads(rawspeed_get_number_of_processor_cores())
+ {
+#endif
+#ifdef HAVE_OPENMP
+#pragma omp for schedule(dynamic, 1)
+#endif
+ for (auto decodeableBand = allDecodeableBands.begin();
+ decodeableBand < allDecodeableBands.end(); ++decodeableBand) {
+ try {
+ decodeableBand->band->decode(decodeableBand->wavelet);
+ } catch (RawspeedException& err) {
+ // Propagate the exception out of OpenMP magic.
+ mRaw->setError(err.what());
+#ifdef HAVE_OPENMP
+#pragma omp atomic write
+ exceptionThrown = true;
+#pragma omp cancel for
+#else
+ throw;
+#endif
+ }
+ }
+
+#ifdef HAVE_OPENMP
+#pragma omp cancel parallel if (exceptionThrown)
+
+ // Parallel region termination is usually disabled by default,
+ // thus we can't just rely on it. Proceed only if decoding did not fail.
+ if (!exceptionThrown) {
+#endif
+ // And now, reconstruct the low-pass bands.
+ for (const ReconstructionStep& step : reconstructionSteps) {
+ step.band.decode(step.wavelet);
+
+#ifdef HAVE_OPENMP
+#pragma omp single nowait
+#endif
+ step.wavelet.clear(); // we no longer need it.
+ }
+
+ // And finally!
+ combineFinalLowpassBands();
+
+#ifdef HAVE_OPENMP
+ }
+ }
+
+ std::string firstErr;
+ if (mRaw->isTooManyErrors(1, &firstErr)) {
+ assert(exceptionThrown);
+ ThrowRDE("Too many errors encountered. Giving up. First Error:\n%s",
+ firstErr.c_str());
+ } else {
+ assert(!exceptionThrown);
+ }
+#endif
+}
+
+void VC5Decompressor::combineFinalLowpassBands() const noexcept {
+ const Array2DRef<uint16_t> out(reinterpret_cast<uint16_t*>(mRaw->getData()),
+ mRaw->dim.x, mRaw->dim.y,
+ mRaw->pitch / sizeof(uint16_t));
+
+ const int width = out.width / 2;
+ const int height = out.height / 2;
+
+ const Array2DRef<const int16_t> lowbands0 = Array2DRef<const int16_t>(
+ channels[0].band.data.data(), channels[0].width, channels[0].height);
+ const Array2DRef<const int16_t> lowbands1 = Array2DRef<const int16_t>(
+ channels[1].band.data.data(), channels[1].width, channels[1].height);
+ const Array2DRef<const int16_t> lowbands2 = Array2DRef<const int16_t>(
+ channels[2].band.data.data(), channels[2].width, channels[2].height);
+ const Array2DRef<const int16_t> lowbands3 = Array2DRef<const int16_t>(
+ channels[3].band.data.data(), channels[3].width, channels[3].height);
+
+ // Convert to RGGB output
+#ifdef HAVE_OPENMP
+#pragma omp for schedule(static) collapse(2)
+#endif
+ for (int row = 0; row < height; ++row) {
+ for (int col = 0; col < width; ++col) {
+ const int mid = 2048;
+
+ int gs = lowbands0(col, row);
+ int rg = lowbands1(col, row) - mid;
+ int bg = lowbands2(col, row) - mid;
+ int gd = lowbands3(col, row) - mid;
+
+ int r = gs + 2 * rg;
+ int b = gs + 2 * bg;
+ int g1 = gs + gd;
+ int g2 = gs - gd;
+
+ out(2 * col + 0, 2 * row + 0) = static_cast<uint16_t>(mVC5LogTable[r]);
+ out(2 * col + 1, 2 * row + 0) = static_cast<uint16_t>(mVC5LogTable[g1]);
+ out(2 * col + 0, 2 * row + 1) = static_cast<uint16_t>(mVC5LogTable[g2]);
+ out(2 * col + 1, 2 * row + 1) = static_cast<uint16_t>(mVC5LogTable[b]);
+ }
+ }
+}
+
+inline void VC5Decompressor::getRLV(BitPumpMSB* bits, int* value,
+ unsigned int* count) {
+ unsigned int iTab;
+
+ static constexpr auto maxBits = 1 + table17.entries[table17.length - 1].size;
+
+ // Ensure the maximum number of bits are cached to make peekBits() as fast as
+ // possible.
+ bits->fill(maxBits);
+ for (iTab = 0; iTab < table17.length; ++iTab) {
+ if (decompandedTable17[iTab].bits ==
+ bits->peekBitsNoFill(decompandedTable17[iTab].size))
+ break;
+ }
+ if (iTab >= table17.length)
+ ThrowRDE("Code not found in codebook");
+
+ bits->skipBitsNoFill(decompandedTable17[iTab].size);
+ *value = decompandedTable17[iTab].value;
+ *count = decompandedTable17[iTab].count;
+ if (*value != 0) {
+ if (bits->getBitsNoFill(1))
+ *value = -(*value);
+ }
+}
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.h b/src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.h
new file mode 100644
index 000000000..268ed2eeb
--- /dev/null
+++ b/src/external/rawspeed/src/librawspeed/decompressors/VC5Decompressor.h
@@ -0,0 +1,229 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2018 Stefan Löffler
+ 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
+*/
+
+#pragma once
+
+#include "common/Array2DRef.h" // for Array2DRef
+#include "common/Common.h" // for ushort16, short16
+#include "common/DefaultInitAllocatorAdaptor.h" // for DefaultInitAllocatorA...
+#include "common/Optional.h" // for Optional
+#include "common/RawImage.h" // for RawImage
+#include "common/SimpleLUT.h" // for SimpleLUT, SimpleLUT...
+#include "decompressors/AbstractDecompressor.h" // for AbstractDecompressor
+#include "io/BitPumpMSB.h" // for BitPumpMSB
+#include "io/ByteStream.h" // for ByteStream
+#include <array> // for array
+#include <cstdint> // for int16_t, uint16_t
+#include <memory> // for unique_ptr
+#include <type_traits> // for underlying_type, und...
+#include <utility> // for move
+#include <vector> // for vector
+
+namespace rawspeed {
+
+const int MAX_NUM_PRESCALE = 8;
+
+// Decompresses VC-5 as used by GoPro
+
+enum class VC5Tag : int16_t {
+ NoTag = 0x0, // synthetic, not an actual tag
+
+ ChannelCount = 0x000c,
+ ImageWidth = 0x0014,
+ ImageHeight = 0x0015,
+ LowpassPrecision = 0x0023,
+ SubbandCount = 0x000E,
+ SubbandNumber = 0x0030,
+ Quantization = 0x0035,
+ ChannelNumber = 0x003e,
+ ImageFormat = 0x0054,
+ MaxBitsPerComponent = 0x0066,
+ PatternWidth = 0x006a,
+ PatternHeight = 0x006b,
+ ComponentsPerSample = 0x006c,
+ PrescaleShift = 0x006d,
+
+ LARGE_CHUNK = 0x2000,
+ SMALL_CHUNK = 0x4000,
+ UniqueImageIdentifier = 0x4004,
+ LargeCodeblock = 0x6000,
+
+ Optional = int16_t(0x8000U), // only signbit set
+};
+inline VC5Tag operator&(VC5Tag LHS, VC5Tag RHS) {
+ using value_type = std::underlying_type<VC5Tag>::type;
+ return static_cast<VC5Tag>(static_cast<value_type>(LHS) &
+ static_cast<value_type>(RHS));
+}
+inline bool matches(VC5Tag LHS, VC5Tag RHS) {
+ // Are there any common bit set?
+ return (LHS & RHS) != VC5Tag::NoTag;
+}
+inline bool is(VC5Tag LHS, VC5Tag RHS) {
+ // Does LHS have all the RHS bits set?
+ return (LHS & RHS) == RHS;
+}
+inline VC5Tag operator-(VC5Tag tag) {
+ using value_type = std::underlying_type<VC5Tag>::type;
+ // Negate
+ return static_cast<VC5Tag>(-static_cast<value_type>(tag));
+}
+
+class VC5Decompressor final : public AbstractDecompressor {
+ RawImage mRaw;
+ ByteStream mBs;
+
+ static constexpr auto VC5_LOG_TABLE_BITWIDTH = 12;
+ int outputBits;
+ SimpleLUT<unsigned, VC5_LOG_TABLE_BITWIDTH> mVC5LogTable;
+
+ void initVC5LogTable();
+
+ static constexpr int numWaveletLevels = 3;
+ static constexpr int numHighPassBands = 3;
+ static constexpr int numLowPassBands = 1;
+ static constexpr int numSubbands =
+ numLowPassBands + numHighPassBands * numWaveletLevels;
+
+ struct {
+ ushort16 iChannel = 0; // 0'th channel is the default
+ Optional<ushort16> iSubband;
+ Optional<ushort16> lowpassPrecision;
+ Optional<short16> quantization;
+
+ const ushort16 imgFormat = 4;
+ const ushort16 patternWidth = 2;
+ const ushort16 patternHeight = 2;
+ const ushort16 cps = 1;
+ } mVC5;
+
+ class Wavelet {
+ public:
+ int width, height;
+ int16_t prescale;
+
+ struct AbstractBand {
+ std::vector<int16_t, DefaultInitAllocatorAdaptor<int16_t>> data;
+ virtual ~AbstractBand() = default;
+ virtual void decode(const Wavelet& wavelet) = 0;
+ };
+ struct ReconstructableBand final : AbstractBand {
+ bool clampUint;
+ std::vector<int16_t, DefaultInitAllocatorAdaptor<int16_t>>
+ lowpass_storage;
+ std::vector<int16_t, DefaultInitAllocatorAdaptor<int16_t>>
+ highpass_storage;
+ explicit ReconstructableBand(bool clampUint_ = false)
+ : clampUint(clampUint_) {}
+ void processLow(const Wavelet& wavelet) noexcept;
+ void processHigh(const Wavelet& wavelet) noexcept;
+ void combine(const Wavelet& wavelet) noexcept;
+ void decode(const Wavelet& wavelet) noexcept final;
+ };
+ struct AbstractDecodeableBand : AbstractBand {
+ ByteStream bs;
+ explicit AbstractDecodeableBand(ByteStream bs_) : bs(std::move(bs_)) {}
+ };
+ struct LowPassBand final : AbstractDecodeableBand {
+ ushort16 lowpassPrecision;
+ LowPassBand(const Wavelet& wavelet, ByteStream bs_,
+ ushort16 lowpassPrecision_);
+ void decode(const Wavelet& wavelet) final;
+ };
+ struct HighPassBand final : AbstractDecodeableBand {
+ int16_t quant;
+ HighPassBand(ByteStream bs_, int16_t quant_)
+ : AbstractDecodeableBand(std::move(bs_)), quant(quant_) {}
+ void decode(const Wavelet& wavelet) final;
+ };
+
+ static constexpr uint16_t numBands = 4;
+ std::array<std::unique_ptr<AbstractBand>, numBands> bands;
+
+ void clear() {
+ for (auto& band : bands)
+ band.reset();
+ }
+
+ void setBandValid(int band);
+ bool isBandValid(int band) const;
+ uint32_t getValidBandMask() const { return mDecodedBandMask; }
+ bool allBandsValid() const;
+
+ void reconstructPass(Array2DRef<int16_t> dst,
+ Array2DRef<const int16_t> high,
+ Array2DRef<const int16_t> low) const noexcept;
+
+ void combineLowHighPass(Array2DRef<int16_t> dst,
+ Array2DRef<const int16_t> low,
+ Array2DRef<const int16_t> high, int descaleShift,
+ bool clampUint /*= false*/) const noexcept;
+
+ Array2DRef<const int16_t> bandAsArray2DRef(unsigned int iBand) const;
+
+ protected:
+ uint32 mDecodedBandMask = 0;
+ };
+
+ struct Channel {
+ std::array<Wavelet, numWaveletLevels> wavelets;
+
+ Wavelet::ReconstructableBand band{/*clampUint*/ true};
+ // the final lowband.
+ int width, height;
+ };
+
+ static constexpr int numChannels = 4;
+ static constexpr int numSubbandsTotal = numSubbands * numChannels;
+ static constexpr int numLowPassBandsTotal = numWaveletLevels * numChannels;
+ std::array<Channel, numChannels> channels;
+
+ struct DecodeableBand {
+ Wavelet::AbstractDecodeableBand* band;
+ const Wavelet& wavelet;
+ DecodeableBand(Wavelet::AbstractDecodeableBand* band_,
+ const Wavelet& wavelet_)
+ : band(band_), wavelet(wavelet_) {}
+ };
+ struct ReconstructionStep {
+ Wavelet& wavelet;
+ Wavelet::ReconstructableBand& band;
+ ReconstructionStep(Wavelet* wavelet_, Wavelet::ReconstructableBand* band_)
+ : wavelet(*wavelet_), band(*band_) {}
+ };
+
+ static inline void getRLV(BitPumpMSB* bits, int* value, unsigned int* count);
+
+ void parseLargeCodeblock(const ByteStream& bs);
+
+ // FIXME: this *should* be threadedable nicely.
+ void combineFinalLowpassBands() const noexcept;
+
+ void parseVC5();
+
+public:
+ VC5Decompressor(ByteStream bs, const RawImage& img);
+
+ void decode(unsigned int offsetX, unsigned int offsetY, unsigned int width,
+ unsigned int height);
+};
+
+} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/io/BitPumpJPEG.h b/src/external/rawspeed/src/librawspeed/io/BitPumpJPEG.h
index d9e562d0a..5cfb42cf0 100644
--- a/src/external/rawspeed/src/librawspeed/io/BitPumpJPEG.h
+++ b/src/external/rawspeed/src/librawspeed/io/BitPumpJPEG.h
@@ -33,6 +33,10 @@ struct JPEGBitPumpTag;
// i.e. we push into the cache from the right and read it from the left
using BitPumpJPEG = BitStream<JPEGBitPumpTag, BitStreamCacheRightInLeftOut>;
+template <> struct BitStreamTraits<BitPumpJPEG> final {
+ static constexpr bool canUseWithHuffmanTable = true;
+};
+
template <>
inline BitPumpJPEG::size_type BitPumpJPEG::fillCache(const uchar8* input)
{
@@ -64,7 +68,7 @@ inline BitPumpJPEG::size_type BitPumpJPEG::fillCache(const uchar8* input)
// Normally we would rewind the pos to the FF byte, but in order to
// prevent potential endless loop on corrupt lossless jpeg, let's not.
- cache.cache &= ~0xFF;
+ cache.cache &= ~0xFFULL; // clear low 8 bits.
cache.cache <<= 64 - cache.fillLevel;
cache.fillLevel = 64;
break;
diff --git a/src/external/rawspeed/src/librawspeed/io/BitPumpLSB.h b/src/external/rawspeed/src/librawspeed/io/BitPumpLSB.h
index c7665b8a7..91a6e11d6 100644
--- a/src/external/rawspeed/src/librawspeed/io/BitPumpLSB.h
+++ b/src/external/rawspeed/src/librawspeed/io/BitPumpLSB.h
@@ -27,12 +27,12 @@
namespace rawspeed {
-struct PlainBitPumpTag;
+struct LSBBitPumpTag;
-// The PlainPump is ordered in LSB bit order,
+// The LSBPump is ordered in LSB bit order,
// i.e. we push into the cache from the left and read it from the right
-using BitPumpLSB = BitStream<PlainBitPumpTag, BitStreamCacheLeftInRightOut>;
+using BitPumpLSB = BitStream<LSBBitPumpTag, BitStreamCacheLeftInRightOut>;
template <>
inline BitPumpLSB::size_type BitPumpLSB::fillCache(const uchar8* input) {
diff --git a/src/external/rawspeed/src/librawspeed/io/BitPumpMSB.h b/src/external/rawspeed/src/librawspeed/io/BitPumpMSB.h
index 9006404ad..bd5d8ed56 100644
--- a/src/external/rawspeed/src/librawspeed/io/BitPumpMSB.h
+++ b/src/external/rawspeed/src/librawspeed/io/BitPumpMSB.h
@@ -33,6 +33,10 @@ struct MSBBitPumpTag;
using BitPumpMSB = BitStream<MSBBitPumpTag, BitStreamCacheRightInLeftOut>;
+template <> struct BitStreamTraits<BitPumpMSB> final {
+ static constexpr bool canUseWithHuffmanTable = true;
+};
+
template <>
inline BitPumpMSB::size_type BitPumpMSB::fillCache(const uchar8* input)
{
diff --git a/src/external/rawspeed/src/librawspeed/io/BitPumpMSB32.h b/src/external/rawspeed/src/librawspeed/io/BitPumpMSB32.h
index ed77c9200..0797ce284 100644
--- a/src/external/rawspeed/src/librawspeed/io/BitPumpMSB32.h
+++ b/src/external/rawspeed/src/librawspeed/io/BitPumpMSB32.h
@@ -33,6 +33,10 @@ struct MSB32BitPumpTag;
using BitPumpMSB32 = BitStream<MSB32BitPumpTag, BitStreamCacheRightInLeftOut>;
+template <> struct BitStreamTraits<BitPumpMSB32> final {
+ static constexpr bool canUseWithHuffmanTable = true;
+};
+
template <>
inline BitPumpMSB32::size_type BitPumpMSB32::fillCache(const uchar8* input)
{
diff --git a/src/external/rawspeed/src/librawspeed/io/BitStream.h b/src/external/rawspeed/src/librawspeed/io/BitStream.h
index 6c151e01d..d9c8037ba 100644
--- a/src/external/rawspeed/src/librawspeed/io/BitStream.h
+++ b/src/external/rawspeed/src/librawspeed/io/BitStream.h
@@ -60,7 +60,7 @@ struct BitStreamCacheLeftInRightOut : BitStreamCacheBase
}
inline uint32 peek(uint32 count) const noexcept {
- return cache & ((1 << count) - 1);
+ return cache & ((1U << count) - 1U);
}
inline void skip(uint32 count) noexcept {
@@ -78,7 +78,7 @@ struct BitStreamCacheRightInLeftOut : BitStreamCacheBase
}
inline uint32 peek(uint32 count) const noexcept {
- return (cache >> (fillLevel - count)) & ((1 << count) - 1);
+ return (cache >> (fillLevel - count)) & ((1U << count) - 1U);
}
inline void skip(uint32 count) noexcept {
@@ -86,6 +86,10 @@ struct BitStreamCacheRightInLeftOut : BitStreamCacheBase
}
};
+template <typename BIT_STREAM> struct BitStreamTraits final {
+ static constexpr bool canUseWithHuffmanTable = false;
+};
+
template <typename Tag, typename Cache>
class BitStream final : public ByteStream {
Cache cache;
@@ -109,15 +113,17 @@ private:
inline void fillSafe() {
assert(data);
if (pos + BitStreamCacheBase::MaxProcessBytes <= size) {
- uchar8 tmp[BitStreamCacheBase::MaxProcessBytes] = {0};
+ std::array<uchar8, BitStreamCacheBase::MaxProcessBytes> tmp;
+ tmp.fill(0);
assert(!(size - pos < BitStreamCacheBase::MaxProcessBytes));
- memcpy(tmp, data + pos, BitStreamCacheBase::MaxProcessBytes);
- pos += fillCache(tmp);
+ memcpy(tmp.data(), data + pos, BitStreamCacheBase::MaxProcessBytes);
+ pos += fillCache(tmp.data());
} else if (pos < size) {
- uchar8 tmp[BitStreamCacheBase::MaxProcessBytes] = {0};
+ std::array<uchar8, BitStreamCacheBase::MaxProcessBytes> tmp;
+ tmp.fill(0);
assert(size - pos < BitStreamCacheBase::MaxProcessBytes);
- memcpy(tmp, data + pos, size - pos);
- pos += fillCache(tmp);
+ memcpy(tmp.data(), data + pos, size - pos);
+ pos += fillCache(tmp.data());
} else if (pos < size + Cache::MaxGetBits / 8) {
// yes, this case needs to continue using Cache::MaxGetBits
// assert(size <= pos);
@@ -156,6 +162,8 @@ public:
return pos - (cache.fillLevel >> 3);
}
+ inline size_type getFillLevel() const { return cache.fillLevel; }
+
// rewinds to the beginning of the buffer.
void resetBufferPosition() {
pos = 0;
diff --git a/src/external/rawspeed/src/librawspeed/io/Buffer.cpp b/src/external/rawspeed/src/librawspeed/io/Buffer.cpp
index 0ce16b7df..7c9307bff 100644
--- a/src/external/rawspeed/src/librawspeed/io/Buffer.cpp
+++ b/src/external/rawspeed/src/librawspeed/io/Buffer.cpp
@@ -19,12 +19,11 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "rawspeedconfig.h"
#include "io/Buffer.h"
-#include "AddressSanitizer.h" // for ASan::RegionIsPoisoned
+#include "AddressSanitizer.h" // for ASan
#include "common/Common.h" // for uchar8, roundUp
-#include "common/Memory.h" // for alignedFree, alignedMalloc
-#include "io/IOException.h" // for IOException (ptr only), ThrowIOE
+#include "common/Memory.h" // for alignedFree, alignedFreeConstPtr, alig...
+#include "io/IOException.h" // for ThrowIOE
#include <cassert> // for assert
#include <memory> // for unique_ptr
diff --git a/src/external/rawspeed/src/librawspeed/io/Buffer.h b/src/external/rawspeed/src/librawspeed/io/Buffer.h
index 77e655e9d..f9419e1f2 100644
--- a/src/external/rawspeed/src/librawspeed/io/Buffer.h
+++ b/src/external/rawspeed/src/librawspeed/io/Buffer.h
@@ -21,15 +21,14 @@
#pragma once
-#include "rawspeedconfig.h"
-#include "AddressSanitizer.h" // for ASan::RegionIsPoisoned
-#include "common/Common.h" // for uchar8, uint32, uint64
+#include "AddressSanitizer.h" // for ASan
+#include "common/Common.h" // for uchar8, uint64, uint32
#include "common/Memory.h" // for alignedFree
-#include "io/Endianness.h" // for getByteSwapped
+#include "io/Endianness.h" // for Endianness, Endianness::little, getHos...
#include "io/IOException.h" // for ThrowIOE
-#include <algorithm> // for swap
#include <cassert> // for assert
#include <memory> // for unique_ptr
+#include <utility> // for swap
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/io/ByteStream.h b/src/external/rawspeed/src/librawspeed/io/ByteStream.h
index a9613e59a..cd2c10599 100644
--- a/src/external/rawspeed/src/librawspeed/io/ByteStream.h
+++ b/src/external/rawspeed/src/librawspeed/io/ByteStream.h
@@ -225,12 +225,12 @@ public:
// special factory function to set up internal buffer with copy of passed data.
// only necessary to create 'fake' TiffEntries (see e.g. RAF)
- static ByteStream createCopy(void* data, size_type size) {
+ static ByteStream createCopy(void* data_, size_type size_) {
ByteStream bs;
- auto* new_data = alignedMalloc<uchar8, 8>(roundUp(size, 8));
- memcpy(new_data, data, size);
+ auto* new_data = alignedMalloc<uchar8, 8>(roundUp(size_, 8));
+ memcpy(new_data, data_, size_);
bs.data = new_data;
- bs.size = size;
+ bs.size = size_;
bs.isOwner = true;
return bs; // hint: copy elision or move will happen
}
diff --git a/src/external/rawspeed/src/librawspeed/io/Endianness.h b/src/external/rawspeed/src/librawspeed/io/Endianness.h
index 777810767..7e05e3d77 100644
--- a/src/external/rawspeed/src/librawspeed/io/Endianness.h
+++ b/src/external/rawspeed/src/librawspeed/io/Endianness.h
@@ -24,6 +24,7 @@
#include "common/Common.h" // for uint32, ushort16, uint64, int32, short16
#include <cassert> // for assert
#include <cstring> // for memcpy
+// IWYU pragma: no_include "io/EndiannessTest.h"
namespace rawspeed {
@@ -66,25 +67,35 @@ inline Endianness getHostEndianness() {
#define BSWAP64(A) __builtin_bswap64(A)
#endif
-inline short16 getByteSwapped(short16 v) { return BSWAP16(v); }
-inline ushort16 getByteSwapped(ushort16 v) { return BSWAP16(v); }
-inline int32 getByteSwapped(int32 v) { return BSWAP32(v); }
-inline uint32 getByteSwapped(uint32 v) { return BSWAP32(v); }
-inline uint64 getByteSwapped(uint64 v) { return BSWAP64(v); }
+inline short16 getByteSwapped(short16 v) {
+ return static_cast<short16>(BSWAP16(static_cast<ushort16>(v)));
+}
+inline ushort16 getByteSwapped(ushort16 v) {
+ return static_cast<ushort16>(BSWAP16(v));
+}
+inline int32 getByteSwapped(int32 v) {
+ return static_cast<int32>(BSWAP32(static_cast<uint32>(v)));
+}
+inline uint32 getByteSwapped(uint32 v) {
+ return static_cast<uint32>(BSWAP32(v));
+}
+inline uint64 getByteSwapped(uint64 v) {
+ return BSWAP64(static_cast<uint64>(v));
+}
// the float/double versions use two memcpy which guarantee strict aliasing
// and are compiled into the same assembly as the popular union trick.
inline float getByteSwapped(float f) {
uint32 i;
memcpy(&i, &f, sizeof(i));
- i = BSWAP32(i);
+ i = getByteSwapped(i);
memcpy(&f, &i, sizeof(i));
return f;
}
inline double getByteSwapped(double d) {
uint64 i;
memcpy(&i, &d, sizeof(i));
- i = BSWAP64(i);
+ i = getByteSwapped(i);
memcpy(&d, &i, sizeof(i));
return d;
}
diff --git a/src/external/rawspeed/src/librawspeed/io/FileIOException.h b/src/external/rawspeed/src/librawspeed/io/FileIOException.h
index 4c0b70164..315a3bd2f 100644
--- a/src/external/rawspeed/src/librawspeed/io/FileIOException.h
+++ b/src/external/rawspeed/src/librawspeed/io/FileIOException.h
@@ -34,6 +34,6 @@ public:
};
#define ThrowFIE(...) \
- ThrowExceptionHelper(rawspeed::FileIOException, __VA_ARGS__);
+ ThrowExceptionHelper(rawspeed::FileIOException, __VA_ARGS__)
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/io/FileReader.cpp b/src/external/rawspeed/src/librawspeed/io/FileReader.cpp
index bfa12ad05..fe1518cc1 100644
--- a/src/external/rawspeed/src/librawspeed/io/FileReader.cpp
+++ b/src/external/rawspeed/src/librawspeed/io/FileReader.cpp
@@ -20,14 +20,13 @@
*/
#include "io/FileReader.h"
-#include "io/Buffer.h" // for Buffer
-#include "io/FileIOException.h" // for FileIOException (ptr only), ThrowFIE
-#include <algorithm> // for move
-#include <cstdio> // for fclose, fseek, fopen, fread, ftell
+#include "io/Buffer.h" // for Buffer, Buffer::size_type
+#include "io/FileIOException.h" // for ThrowFIE
+#include <cstdio> // for fseek, fclose, feof, ferror, fopen
#include <fcntl.h> // for SEEK_END, SEEK_SET
#include <limits> // for numeric_limits
-#include <memory> // for unique_ptr
-#include <type_traits> // for make_unsigned
+#include <memory> // for unique_ptr, make_unique, operator==
+#include <utility> // for move
#if !(defined(__unix__) || defined(__APPLE__))
#ifndef NOMINMAX
diff --git a/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.cpp b/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.cpp
index bb60ed5f7..748caf6cd 100644
--- a/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.cpp
+++ b/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.cpp
@@ -62,7 +62,7 @@ CameraMetaData::CameraMetaData(const char *docname) {
continue;
// Create cameras for aliases.
- for (uint32 i = 0; i < cam->aliases.size(); i++) {
+ for (auto i = 0UL; i < cam->aliases.size(); i++) {
addCamera(std::make_unique<Camera>(cam, i));
}
}
diff --git a/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.h b/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.h
index 31cc442c3..0bc73ac53 100644
--- a/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.h
+++ b/src/external/rawspeed/src/librawspeed/metadata/CameraMetaData.h
@@ -21,11 +21,12 @@
#pragma once
#include "rawspeedconfig.h"
-#include "common/Common.h" // for uint32
-#include <map> // for map
-#include <memory> // for unique_ptr
-#include <string> // for string
-#include <tuple> // for tuple
+#include "common/Common.h" // for uint32
+#include "metadata/Camera.h" // for Camera
+#include <map> // for map
+#include <memory> // for unique_ptr
+#include <string> // for string
+#include <tuple> // for tuple
namespace rawspeed {
diff --git a/src/external/rawspeed/src/librawspeed/metadata/CameraSensorInfo.cpp b/src/external/rawspeed/src/librawspeed/metadata/CameraSensorInfo.cpp
index 50c90ff58..c75ceda27 100644
--- a/src/external/rawspeed/src/librawspeed/metadata/CameraSensorInfo.cpp
+++ b/src/external/rawspeed/src/librawspeed/metadata/CameraSensorInfo.cpp
@@ -19,8 +19,8 @@
*/
#include "metadata/CameraSensorInfo.h"
-#include <algorithm> // for move
-#include <vector> // for vector
+#include <utility> // for move
+#include <vector> // for vector
using std::vector;
diff --git a/src/external/rawspeed/src/librawspeed/metadata/ColorFilterArray.cpp b/src/external/rawspeed/src/librawspeed/metadata/ColorFilterArray.cpp
index afd1249d5..0e9b865c1 100644
--- a/src/external/rawspeed/src/librawspeed/metadata/ColorFilterArray.cpp
+++ b/src/external/rawspeed/src/librawspeed/metadata/ColorFilterArray.cpp
@@ -20,15 +20,15 @@
#include "metadata/ColorFilterArray.h"
#include "common/Common.h" // for writeLog, uint32, DEBUG_PR...
-#include "common/Point.h" // for iPoint2D
+#include "common/Point.h" // for iPoint2D, iPoint2D::value_...
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include <algorithm> // for fill
+#include <cmath> // for abs
#include <cstdarg> // for va_arg, va_end, va_list
#include <cstdlib> // for size_t, abs
#include <map> // for map
#include <stdexcept> // for out_of_range
-#include <string> // for string, allocator
-// IWYU pragma: no_include <bits/std_abs.h>
+#include <string> // for string
using std::vector;
using std::string;
@@ -78,7 +78,7 @@ void ColorFilterArray::setCFA( iPoint2D in_size, ... )
}
va_list arguments;
va_start(arguments, in_size);
- for (uint32 i = 0; i < size.area(); i++ ) {
+ for (auto i = 0UL; i < size.area(); i++) {
cfa[i] = static_cast<CFAColor>(va_arg(arguments, int));
}
va_end (arguments);
diff --git a/src/external/rawspeed/src/librawspeed/parsers/CiffParser.cpp b/src/external/rawspeed/src/librawspeed/parsers/CiffParser.cpp
index 4383aaa74..c32700b0d 100644
--- a/src/external/rawspeed/src/librawspeed/parsers/CiffParser.cpp
+++ b/src/external/rawspeed/src/librawspeed/parsers/CiffParser.cpp
@@ -21,18 +21,19 @@
*/
#include "parsers/CiffParser.h"
-#include "common/Common.h" // for make_unique, trimSpaces
+#include "common/Common.h" // for trimSpaces, uint32, ushort16
#include "decoders/CrwDecoder.h" // for CrwDecoder
#include "decoders/RawDecoder.h" // for RawDecoder
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for getHostEndianness, Endianne...
-#include "parsers/CiffParserException.h" // for CiffParserException (ptr only)
+#include "io/Endianness.h" // for Endianness, Endianness::little
+#include "parsers/CiffParserException.h" // for ThrowCPE
#include "tiff/CiffEntry.h" // for CiffEntry
#include "tiff/CiffIFD.h" // for CiffIFD
-#include "tiff/CiffTag.h" // for CiffTag::CIFF_MAKEMODEL
-#include <memory> // for unique_ptr, default_delete
-#include <string> // for operator==, basic_string
-#include <utility> // for move, pair
+#include "tiff/CiffTag.h" // for CIFF_MAKEMODEL
+#include <memory> // for unique_ptr, make_unique
+#include <string> // for operator==, string
+#include <utility> // for move
+#include <vector> // for vector
using std::string;
diff --git a/src/external/rawspeed/src/librawspeed/parsers/FiffParser.cpp b/src/external/rawspeed/src/librawspeed/parsers/FiffParser.cpp
index 6d4df19eb..d90d3b90a 100644
--- a/src/external/rawspeed/src/librawspeed/parsers/FiffParser.cpp
+++ b/src/external/rawspeed/src/librawspeed/parsers/FiffParser.cpp
@@ -21,22 +21,22 @@
*/
#include "parsers/FiffParser.h"
-#include "common/Common.h" // for make_unique, uint32, uchar8
+#include "common/Common.h" // for uint32, ushort16
#include "decoders/RafDecoder.h" // for RafDecoder
#include "decoders/RawDecoder.h" // for RawDecoder
-#include "io/Buffer.h" // for Buffer
+#include "io/Buffer.h" // for Buffer, DataBuffer
#include "io/ByteStream.h" // for ByteStream
-#include "io/Endianness.h" // for getU32BE, getHostEndianness
+#include "io/Endianness.h" // for Endianness, Endianness::big
#include "parsers/FiffParserException.h" // for ThrowFPE
#include "parsers/RawParser.h" // for RawParser
-#include "parsers/TiffParser.h" // for TiffParser::parse, TiffParser::makeDecoder
+#include "parsers/TiffParser.h" // for TiffParser
#include "parsers/TiffParserException.h" // for TiffParserException
-#include "tiff/TiffEntry.h" // for TiffEntry, TiffDataType::TI...
-#include "tiff/TiffIFD.h" // for TiffIFD, TiffRootIFD, TiffI...
-#include "tiff/TiffTag.h" // for TiffTag, TiffTag::FUJIOLDWB
-#include <algorithm> // for move
+#include "tiff/TiffEntry.h" // for TiffEntry, TIFF_SHORT, TIFF...
+#include "tiff/TiffIFD.h" // for TiffIFD, TiffRootIFDOwner
+#include "tiff/TiffTag.h" // for FUJIOLDWB, FUJI_STRIPBYTECO...
#include <limits> // for numeric_limits
-#include <memory> // for default_delete, unique_ptr
+#include <memory> // for make_unique, unique_ptr
+#include <utility> // for move
using std::numeric_limits;
diff --git a/src/external/rawspeed/src/librawspeed/parsers/TiffParser.cpp b/src/external/rawspeed/src/librawspeed/parsers/TiffParser.cpp
index 221fd35a1..a74bbee4e 100644
--- a/src/external/rawspeed/src/librawspeed/parsers/TiffParser.cpp
+++ b/src/external/rawspeed/src/librawspeed/parsers/TiffParser.cpp
@@ -22,8 +22,8 @@
*/
#include "parsers/TiffParser.h"
-#include "common/Common.h" // for make_unique, trimSpaces
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/Common.h" // for uint32, ushort16
+#include "common/NORangesSet.h" // for set
#include "decoders/ArwDecoder.h" // for ArwDecoder
#include "decoders/Cr2Decoder.h" // for Cr2Decoder
#include "decoders/DcrDecoder.h" // for DcrDecoder
@@ -37,17 +37,16 @@
#include "decoders/NefDecoder.h" // for NefDecoder
#include "decoders/OrfDecoder.h" // for OrfDecoder
#include "decoders/PefDecoder.h" // for PefDecoder
-#include "decoders/RafDecoder.h" // for RafDecoder
#include "decoders/RawDecoder.h" // for RawDecoder
#include "decoders/Rw2Decoder.h" // for Rw2Decoder
#include "decoders/SrwDecoder.h" // for SrwDecoder
#include "decoders/ThreefrDecoder.h" // for ThreefrDecoder
#include "io/ByteStream.h" // for ByteStream
-#include "parsers/TiffParserException.h" // for TiffParserException
+#include "parsers/TiffParserException.h" // for ThrowTPE
#include <cassert> // for assert
#include <cstdint> // for UINT32_MAX
-#include <memory> // for unique_ptr
-#include <string> // for operator==, basic_string
+#include <memory> // for make_unique, unique_ptr
+#include <string> // for string
#include <tuple> // for tie, tuple
#include <vector> // for vector
// IWYU pragma: no_include <ext/alloc_traits.h>
diff --git a/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.cpp b/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.cpp
index 5d762c84a..329b71151 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.cpp
+++ b/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.cpp
@@ -21,11 +21,13 @@
*/
#include "tiff/CiffEntry.h"
-#include "common/Common.h" // for uchar8, uint32, ushort16
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/Common.h" // for uint32, uchar8, ushort16
+#include "common/NORangesSet.h" // for set
+#include "io/Buffer.h" // for Buffer
#include "io/ByteStream.h" // for ByteStream
-#include "parsers/CiffParserException.h" // for CiffParserException (ptr only)
-#include <string> // for string, allocator
+#include "parsers/CiffParserException.h" // for ThrowCPE
+#include <string> // for string
+#include <utility> // for pair
#include <vector> // for vector
using std::string;
diff --git a/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.h b/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.h
index 788d48ac5..2e0873219 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.h
+++ b/src/external/rawspeed/src/librawspeed/tiff/CiffEntry.h
@@ -23,7 +23,7 @@
#pragma once
#include "common/Common.h" // for uint32, uchar8, ushort16
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/NORangesSet.h" // for set
#include "io/ByteStream.h" // for ByteStream
#include "tiff/CiffTag.h" // for CiffTag
#include <string> // for string
@@ -31,7 +31,8 @@
namespace rawspeed {
-class CiffIFD;
+class Buffer;
+class CiffIFD; // IWYU pragma: keep
/*
* Tag data type information.
diff --git a/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.cpp b/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.cpp
index 8c4b4361d..17ac74be1 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.cpp
+++ b/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.cpp
@@ -21,19 +21,17 @@
*/
#include "tiff/CiffIFD.h"
-#include "common/Common.h" // for uint32, ushort16, isIn
-#include "common/NORangesSet.h" // for NORangesSet
-#include "common/RawspeedException.h" // for RawspeedException
+#include "common/Common.h" // for isIn, uint32, ushort16
+#include "common/NORangesSet.h" // for set
#include "io/ByteStream.h" // for ByteStream
-#include "io/IOException.h" // for IOException
-#include "parsers/CiffParserException.h" // for ThrowCPE, CiffParserException
-#include "tiff/CiffEntry.h" // for CiffEntry, CiffDataType::CI...
+#include "parsers/CiffParserException.h" // for ThrowCPE
#include <cassert> // for assert
-#include <map> // for map, _Rb_tree_iterator
-#include <memory> // for unique_ptr
-#include <string> // for allocator, operator==, string
-#include <utility> // for pair
-#include <vector> // for vector
+#include <initializer_list> // for initializer_list
+#include <map> // for map, _Rb_tree_const_iterator
+#include <memory> // for unique_ptr, make_unique
+#include <string> // for operator==, string
+#include <utility> // for move, pair
+#include <vector> // for vector, vector<>::size_type
using std::string;
using std::vector;
@@ -41,6 +39,8 @@ using std::unique_ptr;
namespace rawspeed {
+class Buffer;
+
void CiffIFD::parseIFDEntry(NORangesSet<Buffer>* valueDatas,
const ByteStream* valueData,
ByteStream* dirEntries) {
diff --git a/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.h b/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.h
index e5e05e959..531835321 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.h
+++ b/src/external/rawspeed/src/librawspeed/tiff/CiffIFD.h
@@ -23,7 +23,7 @@
#pragma once
#include "common/Common.h" // for uint32
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/NORangesSet.h" // for set
#include "tiff/CiffEntry.h" // IWYU pragma: keep
#include "tiff/CiffTag.h" // for CiffTag
#include <map> // for map
@@ -33,6 +33,7 @@
namespace rawspeed {
+class Buffer;
class ByteStream;
class CiffIFD final {
diff --git a/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.cpp b/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.cpp
index 44fdba316..9c31f8264 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.cpp
+++ b/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.cpp
@@ -21,15 +21,16 @@
*/
#include "tiff/TiffEntry.h"
-#include "common/Common.h" // for uint32, ushort16, int32
+#include "common/Common.h" // for uint32, short16, ushort16
#include "parsers/TiffParserException.h" // for ThrowTPE
#include "tiff/TiffIFD.h" // for TiffIFD, TiffRootIFD
-#include "tiff/TiffTag.h" // for ::DNGPRIVATEDATA, ::EXIFIFD...
-#include <algorithm> // for move
+#include "tiff/TiffTag.h" // for TiffTag, DNGPRIVATEDATA
#include <cassert> // for assert
#include <cstdint> // for UINT32_MAX
#include <cstring> // for strnlen
+#include <initializer_list> // for initializer_list
#include <string> // for string
+#include <utility> // for move
using std::string;
@@ -38,8 +39,8 @@ namespace rawspeed {
class DataBuffer;
// order see TiffDataType
-const uint32 TiffEntry::datashifts[] = {0, 0, 0, 1, 2, 3, 0,
- 0, 1, 2, 3, 2, 3, 2};
+const std::array<uint32, 14> TiffEntry::datashifts = {0, 0, 0, 1, 2, 3, 0,
+ 0, 1, 2, 3, 2, 3, 2};
// 0-1-2-3-4-5-6-7-8-9-10-11-12-13
TiffEntry::TiffEntry(TiffIFD* parent_, ByteStream* bs) : parent(parent_) {
diff --git a/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.h b/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.h
index 93edcc3e3..3d8825026 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.h
+++ b/src/external/rawspeed/src/librawspeed/tiff/TiffEntry.h
@@ -112,7 +112,7 @@ public:
const DataBuffer& getRootIfdData() const;
protected:
- static const uint32 datashifts[];
+ static const std::array<uint32, 14> datashifts;
};
} // namespace rawspeed
diff --git a/src/external/rawspeed/src/librawspeed/tiff/TiffIFD.cpp b/src/external/rawspeed/src/librawspeed/tiff/TiffIFD.cpp
index 0cdcce9db..4a0a08d09 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/TiffIFD.cpp
+++ b/src/external/rawspeed/src/librawspeed/tiff/TiffIFD.cpp
@@ -22,18 +22,18 @@
*/
#include "tiff/TiffIFD.h"
-#include "common/Common.h" // for getHostEndianness, uint32, make_...
-#include "common/NORangesSet.h" // for NORangesSet
+#include "common/Common.h" // for trimSpaces, uint32
+#include "common/NORangesSet.h" // for set
#include "common/RawspeedException.h" // for RawspeedException
#include "io/IOException.h" // for IOException
#include "tiff/TiffEntry.h" // for TiffEntry
-#include "tiff/TiffTag.h" // for TiffTag, ::DNGPRIVATEDATA, ::EXI...
-#include <algorithm> // for move
+#include "tiff/TiffTag.h" // for TiffTag, MAKE, DNGPRIVATEDATA
+#include <cassert> // for assert
#include <cstdint> // for UINT32_MAX
-#include <map> // for map, _Rb_tree_const_iterator, al...
-#include <memory> // for default_delete, unique_ptr
-#include <string> // for operator==, string, basic_string
-#include <utility> // for pair
+#include <map> // for map, _Rb_tree_const_iterator
+#include <memory> // for unique_ptr, make_unique
+#include <string> // for string, operator==
+#include <utility> // for move, pair
#include <vector> // for vector
using std::string;
diff --git a/src/external/rawspeed/src/librawspeed/tiff/TiffTag.h b/src/external/rawspeed/src/librawspeed/tiff/TiffTag.h
index 4d8a2320c..78129f0b6 100644
--- a/src/external/rawspeed/src/librawspeed/tiff/TiffTag.h
+++ b/src/external/rawspeed/src/librawspeed/tiff/TiffTag.h
@@ -35,6 +35,8 @@ enum TiffTag {
PANASONIC_ISO_SPEED = 23,
NEWSUBFILETYPE = 0x00FE,
SUBFILETYPE = 0x00FF,
+ PANASONIC_BITSPERSAMPLE = 0xa,
+ PANASONIC_RAWFORMAT = 0x2d,
MAKERNOTE_ALT = 0x2e,
IMAGEWIDTH = 0x0100,
@@ -349,6 +351,8 @@ enum TiffTag {
KODAK_KDC_OFFSET = 0xFD04,
KODAK_KDC_WIDTH = 0xFD00,
KODAK_KDC_HEIGHT = 0xFD01,
+ KODAK_KDC_SENSOR_WIDTH = 0xFA13,
+ KODAK_KDC_SENSOR_HEIGHT = 0xFA14,
KODAK_IFD2 = 0xFE00,
};
diff --git a/src/external/rawspeed/src/utilities/CMakeLists.txt b/src/external/rawspeed/src/utilities/CMakeLists.txt
index 3d410e8f0..e0b79b492 100644
--- a/src/external/rawspeed/src/utilities/CMakeLists.txt
+++ b/src/external/rawspeed/src/utilities/CMakeLists.txt
@@ -1,8 +1,6 @@
add_subdirectory(identify)
-if(BUILD_TESTING)
- add_subdirectory(rstest)
-endif()
+add_subdirectory(rstest)
if(BUILD_BENCHMARKING)
add_subdirectory(rsbench)
diff --git a/src/external/rawspeed/src/utilities/identify/CMakeLists.txt b/src/external/rawspeed/src/utilities/identify/CMakeLists.txt
index 779323a1d..08676c228 100644
--- a/src/external/rawspeed/src/utilities/identify/CMakeLists.txt
+++ b/src/external/rawspeed/src/utilities/identify/CMakeLists.txt
@@ -10,10 +10,6 @@ target_compile_definitions(${rsidentify}
target_link_libraries(${rsidentify} rawspeed)
-if(WITH_OPENMP AND OPENMP_FOUND AND TARGET OpenMP::OpenMP)
- target_link_libraries(${rsidentify} OpenMP::OpenMP)
-endif()
-
if(BUILD_TESTING)
add_test(NAME utilities/${rsidentify} COMMAND ${rsidentify})
endif()
diff --git a/src/external/rawspeed/src/utilities/identify/rawspeed-identify.cpp b/src/external/rawspeed/src/utilities/identify/rawspeed-identify.cpp
index 419c41690..f97ee770b 100644
--- a/src/external/rawspeed/src/utilities/identify/rawspeed-identify.cpp
+++ b/src/external/rawspeed/src/utilities/identify/rawspeed-identify.cpp
@@ -19,12 +19,14 @@
#include "RawSpeed-API.h" // for RawImage, RawImageData, iPoint2D, ImageMet...
+#include <array> // for array
#include <cstddef> // for size_t
#include <cstdint> // for uint16_t
-#include <cstdio> // for fprintf, stdout, stderr, printf
-#include <memory> // for unique_ptr
-#include <string> // for string, operator+
+#include <cstdio> // for fprintf, stdout, stderr
+#include <memory> // for unique_ptr, make_unique
+#include <string> // for string, operator+, basic_string
#include <sys/stat.h> // for stat
+#include <vector> // for vector
#ifdef _WIN32
#ifndef NOMINMAX
@@ -34,14 +36,14 @@
#include <Windows.h>
#endif
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#include <omp.h>
#endif
// define this function, it is only declared in rawspeed:
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
extern "C" int rawspeed_get_number_of_processor_cores() {
- return omp_get_num_procs();
+ return omp_get_max_threads();
}
#else
extern "C" int __attribute__((const)) rawspeed_get_number_of_processor_cores() {
@@ -59,7 +61,7 @@ std::string find_cameras_xml(const char *argv0) {
struct stat statbuf;
#ifdef RS_CAMERAS_XML_PATH
- static const char set_camfile[] = RS_CAMERAS_XML_PATH;
+ static const char* set_camfile = RS_CAMERAS_XML_PATH;
if (stat(set_camfile, &statbuf)) {
fprintf(stderr, "WARNING: Couldn't find cameras.xml in '%s'\n",
set_camfile);
@@ -258,7 +260,7 @@ int main(int argc, char* argv[]) { // NOLINT
fprintf(stdout, "pixel_aspect_ratio: %f\n", r->metadata.pixelAspectRatio);
double sum = 0.0F;
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp parallel for default(none) schedule(static) reduction(+ : sum)
#endif
for (int y = 0; y < dimUncropped.y; ++y) {
@@ -274,7 +276,7 @@ int main(int argc, char* argv[]) { // NOLINT
if (r->getDataType() == TYPE_FLOAT32) {
sum = 0.0F;
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp parallel for default(none) schedule(static) reduction(+ : sum)
#endif
for (int y = 0; y < dimUncropped.y; ++y) {
@@ -291,7 +293,7 @@ int main(int argc, char* argv[]) { // NOLINT
} else if (r->getDataType() == TYPE_USHORT16) {
sum = 0.0F;
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp parallel for default(none) schedule(static) reduction(+ : sum)
#endif
for (int y = 0; y < dimUncropped.y; ++y) {
diff --git a/src/external/rawspeed/src/utilities/rsbench/CMakeLists.txt b/src/external/rawspeed/src/utilities/rsbench/CMakeLists.txt
index c76640cad..8db36472e 100644
--- a/src/external/rawspeed/src/utilities/rsbench/CMakeLists.txt
+++ b/src/external/rawspeed/src/utilities/rsbench/CMakeLists.txt
@@ -3,8 +3,4 @@ add_executable(rsbench main.cpp)
target_link_libraries(rsbench rawspeed)
target_link_libraries(rsbench rawspeed_bench)
-if(WITH_OPENMP AND OPENMP_FOUND AND TARGET OpenMP::OpenMP)
- target_link_libraries(rsbench OpenMP::OpenMP)
-endif()
-
add_dependencies(benchmarks rsbench)
diff --git a/src/external/rawspeed/src/utilities/rsbench/main.cpp b/src/external/rawspeed/src/utilities/rsbench/main.cpp
index 10bf5a5ba..133182bf3 100644
--- a/src/external/rawspeed/src/utilities/rsbench/main.cpp
+++ b/src/external/rawspeed/src/utilities/rsbench/main.cpp
@@ -18,17 +18,18 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "RawSpeed-API.h" // for RawDecoder, Buffer, FileReader
-#include <benchmark/benchmark.h> // for State, Benchmark, DoNotOptimize
+#include "RawSpeed-API.h" // for RawDecoder, FileReader, RawImage
+#include "common/ChecksumFile.h" // for ChecksumFileEntry, ReadChecksumFile
+#include <benchmark/benchmark.h> // for State, DoNotOptimize, Initialize
#include <chrono> // for duration, high_resolution_clock
#include <ctime> // for clock, clock_t
-#include <map> // for map<>::mapped_type
#include <memory> // for unique_ptr
-#include <ratio> // for milli, ratio
-#include <string> // for string, to_string
-// IWYU pragma: no_include <sys/time.h>
+#include <ratio> // for ratio
+#include <string> // for string, operator!=, to_string
+#include <sys/time.h> // for CLOCKS_PER_SEC
+#include <vector> // for vector
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#include <omp.h>
#endif
@@ -127,24 +128,24 @@ static inline void BM_RawSpeed(benchmark::State& state, const char* fileName,
pixels = raw->getUncroppedDim().area();
}
- std::string label("FileSize,MB=");
- label += std::to_string(double(map->getSize()) / double(1UL << 20UL));
- label += "; MPix=";
- label += std::to_string(double(pixels) / 1e+06);
- state.SetLabel(label.c_str());
-
- const auto WallTime = WT();
- const auto TotalTime = TT();
- const auto ThreadingFactor = TotalTime.count() / WallTime.count();
+ // These are total over all the `state.iterations()` iterations.
+ const double CPUTime = TT().count();
+ const double WallTime = WT().count();
+ // For each iteration:
state.counters.insert({
- {"Pixels/s", benchmark::Counter(pixels, benchmark::Counter::kIsRate)},
- {"CPUTime,s", TotalTime.count()},
- {"ThreadingFactor", ThreadingFactor},
+ {"CPUTime,s", CPUTime / state.iterations()},
+ {"WallTime,s", WallTime / state.iterations()},
+ {"CPUTime/WallTime", CPUTime / WallTime}, // 'Threading factor'
+ {"Pixels", pixels},
+ {"Pixels/CPUTime", (state.iterations() * pixels) / CPUTime},
+ {"Pixels/WallTime", (state.iterations() * pixels) / WallTime},
+ /* {"Raws", 1}, */
+ {"Raws/CPUTime", state.iterations() / CPUTime},
+ {"Raws/WallTime", state.iterations() / WallTime},
});
-
- state.SetItemsProcessed(state.iterations());
- state.SetBytesProcessed(state.iterations() * map->getSize());
+ // Could also have counters wrt. the filesize,
+ // but i'm not sure they are interesting.
}
static void addBench(const char* fName, std::string tName, int threads) {
@@ -160,11 +161,11 @@ int main(int argc, char** argv) {
benchmark::Initialize(&argc, argv);
auto hasFlag = [argc, argv](std::string flag) {
- bool found = false;
+ int found = 0;
for (int i = 1; i < argc; ++i) {
if (!argv[i] || argv[i] != flag)
continue;
- found = true;
+ found = i;
argv[i] = nullptr;
}
return found;
@@ -172,24 +173,46 @@ int main(int argc, char** argv) {
bool threading = hasFlag("-t");
-#ifdef _OPENMP
- const auto threadsMax = omp_get_num_procs();
+#ifdef HAVE_OPENMP
+ const auto threadsMax = omp_get_max_threads();
#else
const auto threadsMax = 1;
#endif
const auto threadsMin = threading ? 1 : threadsMax;
+ // Were we told to use the repo (i.e. filelist.sha1 in that directory)?
+ int useChecksumFile = hasFlag("-r");
+ std::vector<rawspeed::ChecksumFileEntry> ChecksumFileEntries;
+ if (useChecksumFile && useChecksumFile + 1 < argc) {
+ char*& checksumFileRepo = argv[useChecksumFile + 1];
+ if (checksumFileRepo)
+ ChecksumFileEntries = rawspeed::ReadChecksumFile(checksumFileRepo);
+ checksumFileRepo = nullptr;
+ }
+
+ // If there are normal filenames, append them.
for (int i = 1; i < argc; i++) {
if (!argv[i])
continue;
+ rawspeed::ChecksumFileEntry Entry;
const char* fName = argv[i];
+ // These are supposed to be either absolute paths, or relative the run dir.
+ // We don't do any beautification.
+ Entry.FullFileName = fName;
+ Entry.RelFileName = fName;
+ ChecksumFileEntries.emplace_back(Entry);
+ }
+
+ // And finally, actually add the raws to be benchmarked.
+ for (const auto& Entry : ChecksumFileEntries) {
+ const char* fName = Entry.RelFileName.c_str();
std::string tName(fName);
tName += "/threads:";
for (auto threads = threadsMin; threads <= threadsMax; threads++)
- addBench(fName, tName, threads);
+ addBench(Entry.FullFileName.c_str(), tName, threads);
}
benchmark::RunSpecifiedBenchmarks();
diff --git a/src/external/rawspeed/src/utilities/rstest/CMakeLists.txt b/src/external/rawspeed/src/utilities/rstest/CMakeLists.txt
index b2256f421..dd924d592 100644
--- a/src/external/rawspeed/src/utilities/rstest/CMakeLists.txt
+++ b/src/external/rawspeed/src/utilities/rstest/CMakeLists.txt
@@ -1,10 +1,10 @@
+if(NOT BUILD_TESTING)
+ set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON)
+endif()
+
add_executable(rstest rstest.cpp md5.cpp)
target_link_libraries(rstest rawspeed)
-if(WITH_OPENMP AND OPENMP_FOUND AND TARGET OpenMP::OpenMP)
- target_link_libraries(rstest OpenMP::OpenMP)
-endif()
-
if(BUILD_TESTING)
CHECK_CXX_COMPILER_FLAG_AND_ENABLE_IT(-Wno-suggest-attribute=const)
CHECK_CXX_COMPILER_FLAG_AND_ENABLE_IT(-Wno-suggest-override)
@@ -42,6 +42,6 @@ if(BUILD_BENCHMARKING)
add_dependencies(benchmarks MD5Benchmark)
endif()
-if(ENABLE_SAMPLEBASED_TESTING)
+if(RAWSPEED_ENABLE_SAMPLE_BASED_TESTING)
include(sample-based-testing)
endif()
diff --git a/src/external/rawspeed/src/utilities/rstest/MD5Benchmark.cpp b/src/external/rawspeed/src/utilities/rstest/MD5Benchmark.cpp
index eef07b0aa..d1009b2f9 100644
--- a/src/external/rawspeed/src/utilities/rstest/MD5Benchmark.cpp
+++ b/src/external/rawspeed/src/utilities/rstest/MD5Benchmark.cpp
@@ -50,4 +50,4 @@ static inline void CustomArguments(benchmark::internal::Benchmark* b) {
BENCHMARK(BM_MD5)->Apply(CustomArguments);
-BENCHMARK_MAIN()
+BENCHMARK_MAIN();
diff --git a/src/external/rawspeed/src/utilities/rstest/md5.cpp b/src/external/rawspeed/src/utilities/rstest/md5.cpp
index c6417861e..9ad485490 100644
--- a/src/external/rawspeed/src/utilities/rstest/md5.cpp
+++ b/src/external/rawspeed/src/utilities/rstest/md5.cpp
@@ -38,10 +38,10 @@ namespace rawspeed {
namespace md5 {
// hashes 64 bytes at once
-static void md5_compress(md5_state* state, const uint8_t block[64]);
+static void md5_compress(md5_state* state, const uint8_t* block);
-static void md5_compress(md5_state* state, const uint8_t block[64]) {
- uint32_t schedule[16] = {};
+static void md5_compress(md5_state* state, const uint8_t* block) {
+ std::array<uint32_t, 16> schedule = {{}};
auto LOADSCHEDULE = [&block, &schedule](int i) {
for (int k = 3; k >= 0; k--)
@@ -58,8 +58,8 @@ static void md5_compress(md5_state* state, const uint8_t block[64]) {
auto ROUND_TAIL = [ROTL32, &schedule](uint32_t& a, uint32_t b, uint32_t expr,
uint32_t k, uint32_t s, uint32_t t) {
- a = 0UL + a + expr + t + schedule[k];
- (a) = 0UL + b + ROTL32(a, s);
+ a = uint32_t(0UL + a + expr + t + schedule[k]);
+ (a) = uint32_t(0UL + b + ROTL32(a, s));
};
auto ROUND0 = [ROUND_TAIL](uint32_t& a, uint32_t b, uint32_t c, uint32_t d,
@@ -152,10 +152,10 @@ static void md5_compress(md5_state* state, const uint8_t block[64]) {
ROUND3(c, d, a, b, 2, 15, 0x2AD7D2BB);
ROUND3(b, c, d, a, 9, 21, 0xEB86D391);
- (*state)[0] = 0UL + (*state)[0] + a;
- (*state)[1] = 0UL + (*state)[1] + b;
- (*state)[2] = 0UL + (*state)[2] + c;
- (*state)[3] = 0UL + (*state)[3] + d;
+ (*state)[0] = uint32_t(0UL + (*state)[0] + a);
+ (*state)[1] = uint32_t(0UL + (*state)[1] + b);
+ (*state)[2] = uint32_t(0UL + (*state)[2] + c);
+ (*state)[3] = uint32_t(0UL + (*state)[3] + d);
}
/* Full message hasher */
@@ -167,9 +167,9 @@ void md5_hash(const uint8_t* message, size_t len, md5_state* hash) {
for (i = 0; len - i >= 64; i += 64)
md5_compress(hash, &message[i]);
- uint8_t block[64];
+ std::array<uint8_t, 64> block;
size_t rem = len - i;
- memcpy(block, &message[i], rem);
+ memcpy(block.data(), &message[i], rem);
block[rem] = 0x80;
rem++;
@@ -177,8 +177,8 @@ void md5_hash(const uint8_t* message, size_t len, md5_state* hash) {
memset(&block[rem], 0, 56 - rem);
else {
memset(&block[rem], 0, 64 - rem);
- md5_compress(hash, block);
- memset(block, 0, 56);
+ md5_compress(hash, block.data());
+ memset(block.data(), 0, 56);
}
block[64 - 8] = static_cast<uint8_t>((len & 0x1FU) << 3);
@@ -187,16 +187,16 @@ void md5_hash(const uint8_t* message, size_t len, md5_state* hash) {
block[64 - 8 + i] = static_cast<uint8_t>(len);
len >>= 8;
}
- md5_compress(hash, block);
+ md5_compress(hash, block.data());
}
std::string hash_to_string(const md5_state& hash) {
- char res[2 * sizeof(hash) + 1];
+ std::array<char, 2 * sizeof(hash) + 1> res;
auto* h = reinterpret_cast<const uint8_t*>(&hash[0]);
for (int i = 0; i < static_cast<int>(sizeof(hash)); ++i)
- snprintf(res + 2 * i, 3, "%02x", h[i]);
+ snprintf(&res[2 * i], 3, "%02x", h[i]);
res[32] = 0;
- return res;
+ return res.data();
}
std::string md5_hash(const uint8_t* message, size_t len) {
diff --git a/src/external/rawspeed/src/utilities/rstest/rstest.cpp b/src/external/rawspeed/src/utilities/rstest/rstest.cpp
index c29658297..4e3f235fb 100644
--- a/src/external/rawspeed/src/utilities/rstest/rstest.cpp
+++ b/src/external/rawspeed/src/utilities/rstest/rstest.cpp
@@ -20,37 +20,36 @@
#include "RawSpeed-API.h"
-#include "md5.h" // for md5_hash
+#include "md5.h" // for md5_state, md5_hash, hash_to_string, md5_init
+#include <array> // for array
#include <cassert> // for assert
-#include <chrono> // for milliseconds, steady_clock, duration, dur...
+#include <chrono> // for milliseconds, steady_clock, duration_cast
#include <cstdarg> // for va_end, va_list, va_start
#include <cstdint> // for uint8_t
-#include <cstdio> // for snprintf, size_t, fclose, fopen, fprintf
+#include <cstdio> // for fprintf, fclose, size_t, fopen, ftell, fwrite
#include <cstdlib> // for system
#include <fstream> // IWYU pragma: keep
-#include <iostream> // for cout, cerr, left, internal
+#include <iostream> // for cout, left, cerr, internal
#include <map> // for map
-#include <memory> // for unique_ptr, allocator
+#include <memory> // for allocator, unique_ptr
#include <sstream> // IWYU pragma: keep
-#include <string> // for string, char_traits, operator+, operator<<
-#include <type_traits> // for enable_if<>::type
+#include <string> // for string, operator+, operator<<, char_traits
#include <utility> // for pair
#include <vector> // for vector
-
// IWYU pragma: no_include <ext/alloc_traits.h>
#if !defined(__has_feature) || !__has_feature(thread_sanitizer)
#include <iomanip> // for operator<<, setw
#endif
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#include <omp.h>
#endif
// define this function, it is only declared in rawspeed:
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
extern "C" int rawspeed_get_number_of_processor_cores() {
- return omp_get_num_procs();
+ return omp_get_max_threads();
}
#else
extern "C" int __attribute__((const)) rawspeed_get_number_of_processor_cores() {
@@ -163,14 +162,14 @@ md5::md5_state imgDataHash(const RawImage& raw) {
static void __attribute__((format(printf, 2, 3)))
APPEND(ostringstream* oss, const char* format, ...) {
- char line[1024];
+ std::array<char, 1024> line;
va_list args;
va_start(args, format);
- vsnprintf(line, sizeof(line), format, args);
+ vsnprintf(line.data(), sizeof(line), format, args);
va_end(args);
- *oss << line;
+ *oss << line.data();
}
string img_hash(const RawImage& r) {
@@ -347,7 +346,7 @@ size_t process(const string& filename, const CameraMetaData* metadata,
ifstream hf(hashfile);
if (hf.good() == o.create && !o.force) {
#if !defined(__has_feature) || !__has_feature(thread_sanitizer)
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp critical(io)
#endif
cout << left << setw(55) << filename << ": hash "
@@ -358,7 +357,7 @@ size_t process(const string& filename, const CameraMetaData* metadata,
// to narrow down the list of files that could have causes the crash
#if !defined(__has_feature) || !__has_feature(thread_sanitizer)
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp critical(io)
#endif
cout << left << setw(55) << filename << ": starting decoding ... " << endl;
@@ -385,7 +384,7 @@ size_t process(const string& filename, const CameraMetaData* metadata,
auto time = t();
#if !defined(__has_feature) || !__has_feature(thread_sanitizer)
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp critical(io)
#endif
cout << left << setw(55) << filename << ": " << internal << setw(3)
@@ -533,7 +532,7 @@ int main(int argc, char **argv) {
size_t time = 0;
map<string, string> failedTests;
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp parallel for default(shared) schedule(dynamic, 1) reduction(+ : time)
#endif
for (int i = 1; i < argc; ++i) {
@@ -548,7 +547,7 @@ int main(int argc, char **argv) {
throw;
}
} catch (RawspeedException& e) {
-#ifdef _OPENMP
+#ifdef HAVE_OPENMP
#pragma omp critical(io)
#endif
{
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
diff --git a/src/iop/ashift.c b/src/iop/ashift.c
index 1763b2319..12451780a 100644
--- a/src/iop/ashift.c
+++ b/src/iop/ashift.c
@@ -3750,11 +3750,6 @@ int button_pressed(struct dt_iop_module_t *self, double x, double y, double pres
// gather information about "near"-ness in g->points_idx
get_near(g->points, g->points_idx, g->points_lines_count, pzx * wd, pzy * ht, g->near_delta);
- g->near_delta = dt_conf_get_float("plugins/darkroom/ashift/near_delta");
-
- // gather information about "near"-ness in g->points_idx
- get_near(g->points, g->points_idx, g->points_lines_count, pzx * wd, pzy * ht, g->near_delta);
-
// iterate over all lines close to the pointer and change "selected" state.
// left-click selects and right-click deselects the line
for(int n = 0; g->selecting_lines_version == g->lines_version && n < g->points_lines_count; n++)
diff --git a/src/libs/collect.c b/src/libs/collect.c
index 4ae886881..69befd56e 100644
--- a/src/libs/collect.c
+++ b/src/libs/collect.c
@@ -1178,17 +1178,6 @@ static void list_view(dt_lib_collect_rule_t *dr)
"WHERE %s GROUP BY ROUND(aspect_ratio,1)", where_ext);
break;
- case DT_COLLECTION_PROP_LOCAL_COPY: // local copy, 2 hardcoded alternatives
- gtk_list_store_append(GTK_LIST_STORE(model), &iter);
- gtk_list_store_set(GTK_LIST_STORE(model), &iter, DT_LIB_COLLECT_COL_TEXT, _("copied locally"),
- DT_LIB_COLLECT_COL_ID, 0, DT_LIB_COLLECT_COL_TOOLTIP, _("copied locally"),
- DT_LIB_COLLECT_COL_VISIBLE, TRUE, DT_LIB_COLLECT_COL_PATH, _("copied locally"), -1);
- gtk_list_store_append(GTK_LIST_STORE(model), &iter);
- gtk_list_store_set(GTK_LIST_STORE(model), &iter, DT_LIB_COLLECT_COL_TEXT, _("not copied locally"),
- DT_LIB_COLLECT_COL_ID, 1, DT_LIB_COLLECT_COL_TOOLTIP, _("not copied locally"),
- DT_LIB_COLLECT_COL_VISIBLE, TRUE, DT_LIB_COLLECT_COL_PATH, _("not copied locally"), -1);
- break;
-
case DT_COLLECTION_PROP_COLORLABEL: // colorlabels
g_snprintf(query, sizeof(query), "SELECT CASE "
"color WHEN 0 THEN '%s' WHEN 1 THEN '%s' WHEN 2 THEN '%s' WHEN 3 THEN '%s' WHEN 4 THEN '%s' "
diff --git a/src/libs/navigation.c b/src/libs/navigation.c
index a771b4782..385e8190b 100644
--- a/src/libs/navigation.c
+++ b/src/libs/navigation.c
@@ -496,10 +496,6 @@ static void _zoom_preset_callback(GtkButton *button, gpointer user_data)
{
_zoom_preset_change((uint64_t)user_data);
}
-static void _zoom_preset_3(GtkButton *button, gpointer user_data)
-{
- _zoom_preset_change(4);
-}
static gboolean _lib_navigation_button_press_callback(GtkWidget *widget, GdkEventButton *event,
gpointer user_data)
@@ -530,10 +526,6 @@ static gboolean _lib_navigation_button_press_callback(GtkWidget *widget, GdkEven
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_zoom_preset_callback), (gpointer)4);
gtk_menu_shell_append(menu, item);
- item = gtk_menu_item_new_with_label(_("50%"));
- g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_zoom_preset_3), self);
- gtk_menu_shell_append(menu, item);
-
item = gtk_menu_item_new_with_label(_("100%"));
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(_zoom_preset_callback), (gpointer)2);
gtk_menu_shell_append(menu, item);
diff --git a/src/version_gen.c b/src/version_gen.c
index 75b9b19d6..48713cc1a 100644
--- a/src/version_gen.c
+++ b/src/version_gen.c
@@ -2,13 +2,13 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
- const char darktable_package_version[] = "2.4.4";
- const char darktable_package_string[] = PACKAGE_NAME " 2.4.4";
+ const char darktable_package_version[] = "2.6.0";
+ const char darktable_package_string[] = PACKAGE_NAME " 2.6.0";
const char darktable_last_commit_year[] = "2018";
#else
#define DT_MAJOR 2
- #define DT_MINOR 4
- #define DT_PATCH 4
+ #define DT_MINOR 6
+ #define DT_PATCH 0
#define DT_N_COMMITS 0
#define LAST_COMMIT_YEAR "2018"
#endif