Commit 9c59d274 authored by David Bremner's avatar David Bremner

Importing darktable_2.4.2.orig.tar.xz

parent 5d9c9538
......@@ -219,7 +219,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-f69904f996c4ce87e5976fdee96f005e58dfbe2a")
set(PROJECT_VERSION "archive-6305f8363de0e349f7947b701efb54e035ac0709")
# but was it expanded?
if(PROJECT_VERSION MATCHES Format)
set(PROJECT_VERSION "unknown-version")
......
---
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,-cppcoreguidelines-owning-memory,-fuchsia-*'
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,-cppcoreguidelines-owning-memory,-fuchsia-*,-readability-simd-intrinsics'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
......
......@@ -39,7 +39,7 @@ install:
travis_retry sudo apt-get install -y -q -f --fix-missing rsync;
fi;
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$EXTRA" != "NODOCKER" ]]; then
travis_retry docker pull darktable/rawspeed;
travis_retry travis_wait 5 docker pull darktable/rawspeed;
fi;
before_script:
......
......@@ -28,7 +28,7 @@ if(EXISTS "${PUGIXML_PATH}" AND IS_DIRECTORY "${PUGIXML_PATH}" AND EXISTS "${PUG
)
else()
if(NOT ALLOW_DOWNLOADING_PUGIXML)
message(SEND_ERROR "Did not find pugixml sources! Either pass correct path in PUGIXML_PATH, or enable ALLOW_DOWNLOADING_PUGIXML, or disable BUILD_TESTING.")
message(SEND_ERROR "Did not find pugixml sources! Either pass correct path in PUGIXML_PATH, or enable ALLOW_DOWNLOADING_PUGIXML, or disable WITH_PUGIXML.")
else()
message(WARNING "Did not find pugixml sources! Fetching from web...")
ExternalProject_Add(
......
......@@ -49,6 +49,8 @@ endif()
if(NOT (UNIX OR APPLE))
# bogus warnings about std functions...
list(APPEND CLANG_DISABLED_WARNING_FLAGS "used-but-marked-unused")
# just don't care.
list(APPEND CLANG_DISABLED_WARNING_FLAGS "nonportable-system-include-path")
endif()
foreach(warning ${CLANG_WARNING_FLAGS})
......
......@@ -16,12 +16,12 @@ set (GCC_WARNING_FLAGS
"old-style-casts"
"pointer-arith"
"strict-prototypes"
"suggest-attribute=const"
"suggest-attribute=noreturn"
"suggest-attribute=pure"
"suggest-final-methods"
"suggest-final-types"
"suggest-override"
# "suggest-attribute=const"
# "suggest-attribute=noreturn"
# "suggest-attribute=pure"
# "suggest-final-methods"
# "suggest-final-types"
# "suggest-override"
"traditional"
"vla"
# "cast-align"
......@@ -40,10 +40,12 @@ set (GCC_DISABLED_WARNING_FLAGS
)
set (GCC_NOERROR_WARNING_FLAGS
"suggest-final-methods"
"suggest-final-types"
"suggest-override"
"suggest-attribute=noreturn"
# "suggest-attribute=const"
# "suggest-attribute=noreturn"
# "suggest-attribute=pure"
# "suggest-final-methods"
# "suggest-final-types"
# "suggest-override"
)
foreach(warning ${GCC_WARNING_FLAGS})
......
......@@ -444,7 +444,7 @@
<Color x="0" y="1">GREEN</Color>
<Color x="1" y="1">BLUE</Color>
</CFA>
<Crop x="72" y="52" width="0" height="0"/>
<Crop x="76" y="60" width="-6" height="-6"/>
<Sensor black="2052" white="15000"/>
<Sensor black="2048" white="12277" iso_list="100"/>
<Sensor black="2048" white="11222" iso_list="160 320 640 1250 2500 5000"/>
......@@ -1555,6 +1555,23 @@
<Hint name="wb_offset" value="142"/>
</Hints>
</Camera>
<Camera make="Canon" model="Canon PowerShot G1 X Mark III">
<ID make="Canon" model="PowerShot G1 X Mark III">Canon PowerShot G1 X 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="266" y="42" width="-6" height="-4"/>
<Sensor black="2048" white="16000"/>
<Sensor black="512" white="16000" iso_list="100 125 200 250"/>
<Sensor black="512" white="13200" iso_list="160"/>
<Sensor black="2048" white="13200" iso_list="320 640 1250 2500 5000"/>
<Hints>
<Hint name="wb_offset" value="142"/>
</Hints>
</Camera>
<Camera make="Canon" model="Canon PowerShot G12">
<ID make="Canon" model="PowerShot G12">Canon PowerShot G12</ID>
<CFA width="2" height="2">
......@@ -4599,6 +4616,34 @@
<Crop x="0" y="0" width="-128" height="0"/>
<Sensor black="150" white="3956"/>
</Camera>
<Camera make="Panasonic" model="DMC-FZ2000">
<ID make="Panasonic" model="DMC-FZ2000">Panasonic DMC-FZ2000</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="2095"/>
<Aliases>
<Alias>DMC-FZ2500</Alias>
</Aliases>
</Camera>
<Camera make="Panasonic" model="DMC-FZ2000" mode="3:2">
<ID make="Panasonic" model="DMC-FZ2000">Panasonic DMC-FZ2000</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="2095"/>
<Aliases>
<Alias>DMC-FZ2500</Alias>
</Aliases>
</Camera>
<Camera make="Panasonic" model="DMC-FZ300">
<ID make="Panasonic" model="DMC-FZ300">Panasonic DMC-FZ300</ID>
<CFA width="2" height="2">
......@@ -6650,7 +6695,7 @@
<Color x="0" y="1">BLUE</Color>
<Color x="1" y="1">GREEN</Color>
</CFA>
<Crop x="0" y="0" width="-34" height="0"/>
<Crop x="0" y="0" width="-60" height="0"/>
<Sensor black="150" white="3971"/>
</Camera>
<Camera make="Panasonic" model = "DMC-LX7" mode="4:3">
......@@ -6661,7 +6706,7 @@
<Color x="0" y="1">BLUE</Color>
<Color x="1" y="1">GREEN</Color>
</CFA>
<Crop x="0" y="0" width="-34" height="0"/>
<Crop x="0" y="0" width="-60" height="0"/>
<Sensor black="150" white="3971"/>
</Camera>
<Camera make="Panasonic" model = "DMC-LX7" mode="3:2">
......@@ -7123,6 +7168,7 @@
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="142" white="4095"/>
<Aliases>
<Alias>DMC-ZS100</Alias>
<Alias>DMC-ZS110</Alias>
<Alias>DMC-TZ101</Alias>
<Alias>DMC-TZ110</Alias>
......@@ -7139,6 +7185,7 @@
<Crop x="0" y="0" width="0" height="0"/>
<Sensor black="142" white="4095"/>
<Aliases>
<Alias>DMC-ZS100</Alias>
<Alias>DMC-ZS110</Alias>
<Alias>DMC-TZ101</Alias>
<Alias>DMC-TZ110</Alias>
......@@ -7855,6 +7902,17 @@
<Crop x="0" y="2" width="-10" height="-2"/>
<Sensor black="0" white="4095"/>
</Camera>
<Camera make="SONY" model="DSC-RX0">
<ID make="Sony" model="DSC-RX0">Sony DSC-RX0</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="16620"/>
</Camera>
<Camera make="SONY" model="DSC-RX10">
<ID make="Sony" model="DSC-RX10">Sony DSC-RX10</ID>
<CFA width="2" height="2">
......@@ -7888,6 +7946,17 @@
<Crop x="0" y="0" width="-8" height="0"/>
<Sensor black="800" white="16300"/>
</Camera>
<Camera make="SONY" model="DSC-RX10M4">
<ID make="Sony" model="DSC-RX10M4">Sony DSC-RX10M4</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="16380"/>
</Camera>
<Camera make="SONY" model="DSC-RX100">
<ID make="Sony" model="DSC-RX100">Sony DSC-RX100</ID>
<CFA width="2" height="2">
......
......@@ -50,9 +50,9 @@
</xs:simpleType>
<xs:simpleType name="IDTypeModelType">
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9 \-*()]{1,22}"/>
<xs:pattern value="[a-zA-Z0-9 \-*()]{1,23}"/>
<xs:minLength value="1"/>
<xs:maxLength value="22"/>
<xs:maxLength value="23"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="IDType">
......
......@@ -60,7 +60,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
try {
const rawspeed::Buffer buffer(Data, Size);
auto ifd = rawspeed::TiffParser::parse(buffer);
auto ifd = rawspeed::TiffParser::parse(nullptr, buffer);
// ATM do not care if this is the appropriate decoder.
// only check that the check does not crash.
......
......@@ -44,9 +44,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
const rawspeed::uint32 dec_table = bs.getU32();
const rawspeed::uint32 lowbits = bs.getU32();
rawspeed::Buffer mFile = bs.getBuffer(bs.getRemainSize());
rawspeed::CrwDecompressor c(mRaw, dec_table, lowbits, &mFile);
rawspeed::CrwDecompressor c(mRaw, dec_table, lowbits,
bs.getStream(bs.getRemainSize()));
mRaw->createData();
c.decompress();
......
......@@ -5,6 +5,8 @@
#ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
#define THREAD_SAFETY_ANALYSIS_MUTEX_H
#pragma GCC system_header
// Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers.
#if defined(__clang__) && (!defined(SWIG))
......
......@@ -72,6 +72,8 @@ public:
return x <= rhs.x && y <= rhs.y;
}
bool hasPositiveArea() const { return operator>({0, 0}); }
area_type __attribute__((pure)) area() const {
using signed_area = std::make_signed<area_type>::type;
......
......@@ -135,7 +135,7 @@ void RawImageData::poisonPadding() {
}
}
#else
void __attribute__((const)) RawImageData::poisonPadding() {
void RawImageData::poisonPadding() {
// if we are building without ASAN, then there is no need/way to poison.
// however, i think it is better to have such an empty function rather
// than making this whole function not exist in ASAN-less builds
......@@ -156,7 +156,7 @@ void RawImageData::unpoisonPadding() {
}
}
#else
void __attribute__((const)) RawImageData::unpoisonPadding() {
void RawImageData::unpoisonPadding() {
// if we are building without ASAN, then there is no need/way to poison.
// however, i think it is better to have such an empty function rather
// than making this whole function not exist in ASAN-less builds
......@@ -174,7 +174,7 @@ void RawImageData::checkRowIsInitialized(int row) {
MSAN_MEM_IS_INITIALIZED(curr_line, rowsize);
}
#else
void __attribute__((const)) RawImageData::checkRowIsInitialized(int row) {
void RawImageData::checkRowIsInitialized(int row) {
// if we are building without MSAN, then there is no way to check whether
// the image row was fully initialized. however, i think it is better to
// have such an empty function rather than making this whole function not
......@@ -188,7 +188,7 @@ void RawImageData::checkMemIsInitialized() {
checkRowIsInitialized(j);
}
#else
void __attribute__((const)) RawImageData::checkMemIsInitialized() {
void RawImageData::checkMemIsInitialized() {
// if we are building without MSAN, then there is no way to check whether
// the image data was fully initialized. however, i think it is better to
// have such an empty function rather than making this whole function not
......
......@@ -3,7 +3,7 @@
Copyright (C) 2009-2014 Klaus Post
Copyright (C) 2014 Pedro Côrte-Real
Copyright (C) 2015 Roman Lebedev
Copyright (C) 2015-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
......@@ -48,13 +48,25 @@ namespace rawspeed {
class CameraMetaData;
bool CrwDecoder::isCRW(const Buffer* input) {
static const char magic[] = "HEAPCCDR";
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);
}
CrwDecoder::CrwDecoder(std::unique_ptr<const CiffIFD> rootIFD,
const Buffer* file)
: RawDecoder(file), mRootIFD(move(rootIFD)) {}
RawImage CrwDecoder::decodeRawInternal() {
const CiffEntry* sensorInfo = mRootIFD->getEntryRecursive(CIFF_SENSORINFO);
const CiffEntry* rawData = mRootIFD->getEntry(CIFF_RAWDATA);
if (!rawData)
ThrowRDE("Couldn't find the raw data chunk");
const CiffEntry* sensorInfo = mRootIFD->getEntryRecursive(CIFF_SENSORINFO);
if (!sensorInfo || sensorInfo->count < 6 || sensorInfo->type != CIFF_SHORT)
ThrowRDE("Couldn't find image sensor info");
......@@ -72,7 +84,7 @@ RawImage CrwDecoder::decodeRawInternal() {
bool lowbits = ! hints.has("no_decompressed_lowbits");
CrwDecompressor c(mRaw, dec_table, lowbits, mFile);
CrwDecompressor c(mRaw, dec_table, lowbits, rawData->getData());
mRaw->createData();
c.decompress();
......
......@@ -40,6 +40,7 @@ public:
RawImage decodeRawInternal() override;
void checkSupportInternal(const CameraMetaData* meta) override;
void decodeMetaDataInternal(const CameraMetaData* meta) override;
static bool isCRW(const Buffer* input);
protected:
int getDecoderVersion() const override { return 0; }
......
......@@ -203,22 +203,7 @@ void DngDecoder::parseCFA(const TiffIFD* raw) {
mRaw->cfa.shiftDown(aa[0]);
}
void DngDecoder::decodeData(const TiffIFD* raw, uint32 sample_format) {
if (compression == 8 && sample_format != 3) {
ThrowRDE("Only float format is supported for "
"deflate-compressed data.");
} else if ((compression == 7 || compression == 0x884c) &&
sample_format != 1) {
ThrowRDE("Only 16 bit unsigned data supported for "
"JPEG-compressed data.");
}
uint32 predictor = -1;
if (raw->hasEntry(PREDICTOR))
predictor = raw->getEntry(PREDICTOR)->getU32();
AbstractDngDecompressor slices(mRaw, compression, mFixLjpeg, bps, predictor);
DngTilingDescription DngDecoder::getTilingDescription(const TiffIFD* raw) {
if (raw->hasEntry(TILEOFFSETS)) {
const uint32 tilew = raw->getEntry(TILEWIDTH)->getU32();
const uint32 tileh = raw->getEntry(TILELENGTH)->getU32();
......@@ -250,73 +235,77 @@ void DngDecoder::decodeData(const TiffIFD* raw, uint32 sample_format) {
tilesX, tilesY);
}
const uint32 nTiles = tilesX * tilesY;
assert(nTiles > 0);
slices.slices.reserve(nTiles);
for (uint32 y = 0; y < tilesY; y++) {
for (uint32 x = 0; x < tilesX; x++) {
const auto s = x + y * tilesX;
const auto offset = offsets->getU32(s);
const auto count = counts->getU32(s);
if (count < 1)
ThrowRDE("Tile %u;%u is empty", x, y);
return {mRaw->dim, tilew, tileh};
}
ByteStream bs(mFile->getSubView(offset, count), 0);
// Strips
TiffEntry* offsets = raw->getEntry(STRIPOFFSETS);
TiffEntry* counts = raw->getEntry(STRIPBYTECOUNTS);
const uint32 offX = tilew * x;
const uint32 offY = tileh * y;
if (counts->count != offsets->count) {
ThrowRDE("Byte count number does not match strip size: "
"count:%u, stips:%u ",
counts->count, offsets->count);
}
DngSliceElement e(bs, offX, offY, tilew, tileh);
slices.slices.emplace_back(e);
}
}
uint32 yPerSlice = raw->hasEntry(ROWSPERSTRIP)
? raw->getEntry(ROWSPERSTRIP)->getU32()
: mRaw->dim.y;
assert(slices.slices.size() == nTiles);
} else { // Strips
TiffEntry* offsets = raw->getEntry(STRIPOFFSETS);
TiffEntry* counts = raw->getEntry(STRIPBYTECOUNTS);
if (yPerSlice == 0 || yPerSlice > static_cast<uint32>(mRaw->dim.y) ||
roundUpDivision(mRaw->dim.y, yPerSlice) != counts->count) {
ThrowRDE("Invalid y per slice %u or strip count %u (height = %u)",
yPerSlice, counts->count, mRaw->dim.y);
}
if (counts->count != offsets->count) {
ThrowRDE("Byte count number does not match strip size: "
"count:%u, stips:%u ",
counts->count, offsets->count);
}
return {mRaw->dim, static_cast<uint32>(mRaw->dim.x), yPerSlice};
}
uint32 yPerSlice = raw->hasEntry(ROWSPERSTRIP) ?
raw->getEntry(ROWSPERSTRIP)->getU32() : mRaw->dim.y;
void DngDecoder::decodeData(const TiffIFD* raw, uint32 sample_format) {
if (compression == 8 && sample_format != 3) {
ThrowRDE("Only float format is supported for "
"deflate-compressed data.");
} else if ((compression == 7 || compression == 0x884c) &&
sample_format != 1) {
ThrowRDE("Only 16 bit unsigned data supported for "
"JPEG-compressed data.");
}
if (yPerSlice == 0 || yPerSlice > static_cast<uint32>(mRaw->dim.y) ||
roundUpDivision(mRaw->dim.y, yPerSlice) != counts->count) {
ThrowRDE("Invalid y per slice %u or strip count %u (height = %u)",
yPerSlice, counts->count, mRaw->dim.y);
}
uint32 predictor = -1;
if (raw->hasEntry(PREDICTOR))
predictor = raw->getEntry(PREDICTOR)->getU32();
slices.slices.reserve(counts->count);
AbstractDngDecompressor slices(mRaw, getTilingDescription(raw), compression,
mFixLjpeg, bps, predictor);
uint32 offY = 0;
for (uint32 s = 0; s < counts->count; s++) {
const auto offset = offsets->getU32(s);
const auto count = counts->getU32(s);
slices.slices.reserve(slices.dsc.numTiles);
if (count < 1)
ThrowRDE("Slice %u is empty", s);
TiffEntry* offsets = nullptr;
TiffEntry* counts = nullptr;
if (raw->hasEntry(TILEOFFSETS)) {
offsets = raw->getEntry(TILEOFFSETS);
counts = raw->getEntry(TILEBYTECOUNTS);
} else { // Strips
offsets = raw->getEntry(STRIPOFFSETS);
counts = raw->getEntry(STRIPBYTECOUNTS);
}
assert(slices.dsc.numTiles == offsets->count);
assert(slices.dsc.numTiles == counts->count);
assert(offY < static_cast<uint32>(mRaw->dim.y));
for (auto n = 0U; n < slices.dsc.numTiles; n++) {
const auto offset = offsets->getU32(n);
const auto count = counts->getU32(n);
ByteStream bs(mFile->getSubView(offset, count), 0);
DngSliceElement e(bs, /*offsetX=*/0, offY, mRaw->dim.x, yPerSlice);
if (count < 1)
ThrowRDE("Tile %u is empty", n);
slices.slices.emplace_back(e);
offY += yPerSlice;
}
ByteStream bs(mFile->getSubView(offset, count), 0,
mRootIFD->rootBuffer.getByteOrder());
assert(static_cast<uint32>(mRaw->dim.y) <= offY);
assert(slices.slices.size() == counts->count);
slices.slices.emplace_back(slices.dsc, n, bs);
}
assert(slices.slices.size() == slices.dsc.numTiles);
if (slices.slices.empty())
ThrowRDE("No valid slices found.");
......@@ -382,7 +371,7 @@ RawImage DngDecoder::decodeRawInternal() {
mRaw->dim.x = raw->getEntry(IMAGEWIDTH)->getU32();
mRaw->dim.y = raw->getEntry(IMAGELENGTH)->getU32();
if (mRaw->dim.x == 0 || mRaw->dim.y == 0)
if (!mRaw->dim.hasPositiveArea())
ThrowRDE("Image has zero size");
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
......@@ -631,8 +620,8 @@ bool DngDecoder::decodeMaskedAreas(const TiffIFD* raw) {
/* Since we may both have short or int, copy it to int array. */
auto rects = masked->getU32Array(nrects*4);
const iRectangle2D fullImage(0, 0, mRaw->getUncroppedDim().x - 1,
mRaw->getUncroppedDim().y - 1);
const iRectangle2D fullImage(0, 0, mRaw->getUncroppedDim().x,
mRaw->getUncroppedDim().y);
const iPoint2D top = mRaw->getCropOffset();
for (uint32 i = 0; i < nrects; i++) {
......
......@@ -32,6 +32,8 @@ class CameraMetaData;
class Buffer;
struct DngTilingDescription;
class DngDecoder final : public AbstractTiffDecoder
{
public:
......@@ -48,6 +50,7 @@ protected:
bool mFixLjpeg;
void dropUnsuportedChunks(std::vector<const TiffIFD*>* data);
void parseCFA(const TiffIFD* raw);
DngTilingDescription getTilingDescription(const TiffIFD* raw);
void decodeData(const TiffIFD* raw, uint32 sample_format);
void handleMetadata(const TiffIFD* raw);
bool decodeMaskedAreas(const TiffIFD* raw);
......
......@@ -124,7 +124,7 @@ void MrwDecoder::parseHeader() {
case 0x545457: // TTW
// Base value for offsets needs to be at the beginning of the TIFF block,
// not the file
rootIFD = TiffParser::parse(bs.getBuffer(len));
rootIFD = TiffParser::parse(nullptr, bs.getBuffer(len));
break;
case 0x574247: // WBG
bs.skipBytes(4); // 4 factors
......
......@@ -486,7 +486,7 @@ void NefDecoder::decodeMetaDataInternal(const CameraMetaData* meta) {
mRootIFD->getEntryRecursive(static_cast<TiffTag>(0x001d))
->getString();
if (serial.length() > 9)
ThrowRDE("Serial number is too long (%lu)", serial.length());
ThrowRDE("Serial number is too long (%zu)", serial.length());
uint32 serialno = 0;
for (unsigned char c : serial) {
if (c >= '0' && c <= '9')
......
......@@ -124,8 +124,7 @@ void RawDecoder::decodeUncompressed(const TiffIFD *rawIFD, BitOrder order) {
mRaw->whitePoint = (1UL << bitPerPixel) - 1UL;
offY = 0;
for (uint32 i = 0; i < slices.size(); i++) {
RawSlice slice = slices[i];
for (const RawSlice& slice : slices) {
UncompressedDecompressor u(*mFile, slice.offset, slice.count, mRaw);
iPoint2D size(width, slice.h);
iPoint2D pos(0, offY);
......@@ -135,22 +134,9 @@ void RawDecoder::decodeUncompressed(const TiffIFD *rawIFD, BitOrder order) {
const auto inputPitch = width * bitPerPixel / 8;
if (!inputPitch)
ThrowRDE("Bad input pitch. Can not decode anything.");
try {
u.readUncompressedRaw(size, pos, inputPitch, bitPerPixel, order);
} catch (RawDecoderException &e) {
if (i>0)
mRaw->setError(e.what());
else
throw;
} catch (IOException &e) {
if (i>0)
mRaw->setError(e.what());
else {
ThrowRDE("IO error occurred in first slice, unable to decode more. "
"Error is: %s",
e.what());
}
}
u.readUncompressedRaw(size, pos, inputPitch, bitPerPixel, order);
offY += slice.h;
}
}
......
......@@ -59,23 +59,9 @@ void AbstractDngDecompressor::decompressThreaded(
UncompressedDecompressor decompressor(e->bs, mRaw);
size_t thisTileLength =
e->offY + e->height > static_cast<uint32>(mRaw->dim.y)
? mRaw->dim.y - e->offY
: e->height;
size_t thisTileWidth =
e->offX + e->width > static_cast<uint32>(mRaw->dim.x)
? mRaw->dim.x - e->offX
: e->width;
if (thisTileLength == 0)
ThrowRDE("Tile is empty. Can not decode!");
iPoint2D tileSize(thisTileWidth, thisTileLength);
iPoint2D tileSize(e->width, e->height);
iPoint2D pos(e->offX, e->offY);
// FIXME: does bytestream have correct byteorder from the src file?
bool big_endian = e->bs.getByteOrder() == Endianness::big;
// DNG spec says that if not 8 or 16 bit/sample, always use big endian
......@@ -85,10 +71,10 @@ void AbstractDngDecompressor::decompressThreaded(
try {
const uint32 inputPixelBits = mRaw->getCpp() * mBps;
if (e->width > std::numeric_limits<int>::max() / inputPixelBits)
if (e->dsc.tileW > std::numeric_limits<int>::max() / inputPixelBits)
ThrowIOE("Integer overflow when calculating input pitch");
const int inputPitchBits = inputPixelBits * e->width;
const int inputPitchBits = inputPixelBits * e->dsc.tileW;
assert(inputPitchBits > 0);
if (inputPitchBits % 8 != 0) {
......@@ -131,7 +117,8 @@ void AbstractDngDecompressor::decompressThreaded(
DeflateDecompressor z(e->bs, mRaw, mPredictor, mBps);
try {
z.decode(&uBuffer, e->width, e->height, e->offX, e->offY);
z.decode(&uBuffer, e->dsc.tileW, e->dsc.tileH, e->width, e->height,
e->offX, e->offY);
} catch (RawDecoderException& err) {
mRaw->setError(err.what());
} catch (IOException& err) {
......
......@@ -23,6 +23,7 @@
#include "common/Common.h" // for uint32
#include "decompressors/AbstractParallelizedDecompressor.h" // for Abstract...
#include "io/ByteStream.h" // for ByteStream
#include <cassert> // for assert
#include <utility> // for move
#include <vector> // for vector
......@@ -30,29 +31,103 @@ namespace rawspeed {
class RawImage;
struct DngSliceElement {
DngSliceElement(ByteStream bs_, uint32 offsetX, uint32 offsetY, uint32 w,
uint32 h)
: bs(std::move(bs_)), offX(offsetX), offY(offsetY), width(w), height(h) {}