diff --git a/data/cameras.xml b/data/cameras.xml
index 6f81d178f..988ba89f6 100644
--- a/data/cameras.xml
+++ b/data/cameras.xml
@@ -14359,6 +14359,24 @@
+
+ Sinar eVolution 75
+
+ GREEN
+ RED
+ BLUE
+ GREEN
+
+
+
+
+
+ 16442 -2956 -2422
+ -2877 12128 750
+ -1136 6066 4559
+
+
+
Sinar Hy6
diff --git a/data/cameras.xsd b/data/cameras.xsd
index 25b0d4187..837db6e78 100644
--- a/data/cameras.xsd
+++ b/data/cameras.xsd
@@ -473,6 +473,7 @@
+
diff --git a/fuzz/all-fuzzers.txt b/fuzz/all-fuzzers.txt
index 764a06036..8830122d6 100644
--- a/fuzz/all-fuzzers.txt
+++ b/fuzz/all-fuzzers.txt
@@ -66,6 +66,7 @@ TiffDecoderFuzzer-OrfDecoder
TiffDecoderFuzzer-PefDecoder
TiffDecoderFuzzer-Rw2Decoder
TiffDecoderFuzzer-SrwDecoder
+TiffDecoderFuzzer-StiDecoder
TiffDecoderFuzzer-ThreefrDecoder
TiffParserFuzzer-GetDecoder
TiffParserFuzzer-GetDecoder-Decode
diff --git a/fuzz/librawspeed/decoders/TiffDecoders/CMakeLists.txt b/fuzz/librawspeed/decoders/TiffDecoders/CMakeLists.txt
index 54122ff0b..fc7cb002f 100644
--- a/fuzz/librawspeed/decoders/TiffDecoders/CMakeLists.txt
+++ b/fuzz/librawspeed/decoders/TiffDecoders/CMakeLists.txt
@@ -32,6 +32,7 @@ set(DECODERS
"PefDecoder"
"Rw2Decoder"
"SrwDecoder"
+ "StiDecoder"
"ThreefrDecoder"
)
diff --git a/fuzz/librawspeed/decoders/TiffDecoders/main.cpp b/fuzz/librawspeed/decoders/TiffDecoders/main.cpp
index 5e1cc5c9d..dd09f952b 100644
--- a/fuzz/librawspeed/decoders/TiffDecoders/main.cpp
+++ b/fuzz/librawspeed/decoders/TiffDecoders/main.cpp
@@ -39,6 +39,7 @@
#include "decoders/RafDecoder.h" // IWYU pragma: keep
#include "decoders/Rw2Decoder.h" // IWYU pragma: keep
#include "decoders/SrwDecoder.h" // IWYU pragma: keep
+#include "decoders/StiDecoder.h" // IWYU pragma: keep
#include "decoders/ThreefrDecoder.h" // IWYU pragma: keep
#include "io/Buffer.h" // for Buffer
#include "metadata/CameraMetaData.h" // for CameraMetaData
diff --git a/src/librawspeed/decoders/CMakeLists.txt b/src/librawspeed/decoders/CMakeLists.txt
index 654116331..beb2ed1fd 100644
--- a/src/librawspeed/decoders/CMakeLists.txt
+++ b/src/librawspeed/decoders/CMakeLists.txt
@@ -44,6 +44,8 @@ FILE(GLOB SOURCES
"SimpleTiffDecoder.h"
"SrwDecoder.cpp"
"SrwDecoder.h"
+ "StiDecoder.cpp"
+ "StiDecoder.h"
"ThreefrDecoder.cpp"
"ThreefrDecoder.h"
)
diff --git a/src/librawspeed/decoders/StiDecoder.cpp b/src/librawspeed/decoders/StiDecoder.cpp
new file mode 100644
index 000000000..02df2949b
--- /dev/null
+++ b/src/librawspeed/decoders/StiDecoder.cpp
@@ -0,0 +1,97 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2023 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 "decoders/StiDecoder.h"
+#include "adt/Point.h" // for iPoint2D
+#include "decoders/RawDecoderException.h" // for ThrowException
+#include "decompressors/HasselbladLJpegDecoder.h" // for HasselbladLJpegDec...
+#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
+#include "io/Buffer.h" // for Buffer, DataBuffer
+#include "io/ByteStream.h" // for ByteStream
+#include "io/Endianness.h" // for Endianness, Endian...
+#include "metadata/ColorFilterArray.h" // for CFAColor, CFAColor...
+#include "tiff/TiffEntry.h" // for TiffEntry
+#include "tiff/TiffIFD.h" // for TiffRootIFD, TiffIFD
+#include "tiff/TiffTag.h" // for TiffTag, TiffTag::...
+#include // for array
+#include // for uint32_t
+#include // for unique_ptr, allocator
+#include // for operator==, string
+
+namespace rawspeed {
+
+class CameraMetaData;
+
+bool StiDecoder::isAppropriateDecoder(const TiffRootIFD* rootIFD,
+ [[maybe_unused]] Buffer file) {
+ const auto id = rootIFD->getID();
+ const std::string& make = id.make;
+
+ // FIXME: magic
+
+ return make == "Sinar AG";
+}
+
+RawImage StiDecoder::decodeRawInternal() {
+ const auto* raw = mRootIFD->getIFDWithTag(TiffTag::TILEOFFSETS, 0);
+ uint32_t width = raw->getEntry(TiffTag::IMAGEWIDTH)->getU32();
+ uint32_t height = raw->getEntry(TiffTag::IMAGELENGTH)->getU32();
+ uint32_t compression = raw->getEntry(TiffTag::COMPRESSION)->getU32();
+
+ mRaw->dim = iPoint2D(width, height);
+
+ if (1 != compression)
+ ThrowRDE("Unexpected compression type.");
+
+ DecodeUncompressed(raw);
+ return mRaw;
+}
+
+void StiDecoder::DecodeUncompressed(const TiffIFD* raw) const {
+ if (mRaw->getDataType() != RawImageType::UINT16)
+ ThrowRDE("Unexpected data type");
+
+ if (mRaw->getCpp() != 1 || mRaw->getBpp() != sizeof(uint16_t))
+ ThrowRDE("Unexpected cpp: %u", mRaw->getCpp());
+
+ // FIXME: could be wrong.
+ if (!mRaw->dim.hasPositiveArea() || mRaw->dim.x % 2 != 0 ||
+ mRaw->dim.y % 2 != 0 || mRaw->dim.x > 4992 || mRaw->dim.y > 6668) {
+ ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x,
+ mRaw->dim.y);
+ }
+
+ uint32_t off = raw->getEntry(TiffTag::TILEOFFSETS)->getU32();
+ uint32_t count = raw->getEntry(TiffTag::TILEBYTECOUNTS)->getU32();
+
+ const ByteStream bs(
+ DataBuffer(mFile.getSubView(off, count), Endianness::little));
+
+ UncompressedDecompressor u(bs, mRaw, iRectangle2D({0, 0}, mRaw->dim),
+ 2 * mRaw->dim.x, 16, BitOrder::MSB);
+ mRaw->createData();
+ u.readUncompressedRaw();
+}
+
+void StiDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
+ setMetaData(meta, "", 0);
+}
+
+} // namespace rawspeed
diff --git a/src/librawspeed/decoders/StiDecoder.h b/src/librawspeed/decoders/StiDecoder.h
new file mode 100644
index 000000000..4ec101f76
--- /dev/null
+++ b/src/librawspeed/decoders/StiDecoder.h
@@ -0,0 +1,48 @@
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2023 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/RawImage.h" // for RawImage
+#include "decoders/AbstractTiffDecoder.h" // for AbstractTiffDecoder
+#include "io/Buffer.h" // for Buffer
+#include "tiff/TiffIFD.h" // for TiffRootIFD (ptr only)
+#include // for move
+
+namespace rawspeed {
+
+class Buffer;
+class CameraMetaData;
+
+class StiDecoder final : public AbstractTiffDecoder {
+public:
+ static bool isAppropriateDecoder(const TiffRootIFD* rootIFD, Buffer file);
+ StiDecoder(TiffRootIFDOwner&& root, Buffer file)
+ : AbstractTiffDecoder(std::move(root), file) {}
+
+ RawImage decodeRawInternal() override;
+ void decodeMetaDataInternal(const CameraMetaData* meta) override;
+
+private:
+ [[nodiscard]] int getDecoderVersion() const override { return 0; }
+ void DecodeUncompressed(const TiffIFD* raw) const;
+};
+
+} // namespace rawspeed
diff --git a/src/librawspeed/parsers/TiffParser.cpp b/src/librawspeed/parsers/TiffParser.cpp
index 742892a62..17f1872ab 100644
--- a/src/librawspeed/parsers/TiffParser.cpp
+++ b/src/librawspeed/parsers/TiffParser.cpp
@@ -38,6 +38,7 @@
#include "decoders/PefDecoder.h" // for PefDecoder
#include "decoders/Rw2Decoder.h" // for Rw2Decoder
#include "decoders/SrwDecoder.h" // for SrwDecoder
+#include "decoders/StiDecoder.h" // for StiDecoder
#include "decoders/ThreefrDecoder.h" // for ThreefrDecoder
#include "io/Buffer.h" // for Buffer, DataBuffer
#include "io/ByteStream.h" // for ByteStream
@@ -120,7 +121,7 @@ std::unique_ptr TiffParser::constructor(TiffRootIFDOwner&& root,
}
const std::array,
- 16>
+ 17>
TiffParser::Map = {{
DECODER(DngDecoder),
DECODER(MosDecoder),
@@ -137,6 +138,7 @@ const std::array,
DECODER(DcsDecoder),
DECODER(KdcDecoder),
DECODER(ErfDecoder),
+ DECODER(StiDecoder),
DECODER(ThreefrDecoder),
}};
diff --git a/src/librawspeed/parsers/TiffParser.h b/src/librawspeed/parsers/TiffParser.h
index dbca26c8f..ce4ab4f77 100644
--- a/src/librawspeed/parsers/TiffParser.h
+++ b/src/librawspeed/parsers/TiffParser.h
@@ -55,7 +55,7 @@ class TiffParser final : public RawParser {
using checker_t = bool (*)(const TiffRootIFD* root, Buffer data);
using constructor_t = std::unique_ptr (*)(TiffRootIFDOwner&& root,
Buffer data);
- static const std::array, 16> Map;
+ static const std::array, 17> Map;
};
} // namespace rawspeed