Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion data/cameras.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13966,8 +13966,23 @@
</ColorMatrix>
</ColorMatrices>
</Camera>
<Camera make="SONY" model="ILCE-7RM6" supported="unknown-no-samples">
<Camera make="SONY" model="ILCE-7RM6">
<ID make="Sony" model="ILCE-7RM6">Sony ILCE-7RM6</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="512" white="16383"/>
<ColorMatrices>
<ColorMatrix planes="3">
<ColorMatrixRow plane="0">11765 -5595 -1192</ColorMatrixRow>
<ColorMatrixRow plane="1">-3689 11507 2485</ColorMatrixRow>
<ColorMatrixRow plane="2">51 681 5731</ColorMatrixRow>
</ColorMatrix>
</ColorMatrices>
</Camera>
<Camera make="SONY" model="ILCE-7S">
<ID make="Sony" model="ILCE-7S">Sony ILCE-7S</ID>
Expand Down
1 change: 1 addition & 0 deletions fuzz/all-fuzzers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ SamsungV1DecompressorFuzzer
SamsungV2DecompressorFuzzer
SonyArw1DecompressorFuzzer
SonyArw2DecompressorFuzzer
SonyArw6DecompressorFuzzer
TiffDecoderFuzzer-ArwDecoder
TiffDecoderFuzzer-Cr2Decoder
TiffDecoderFuzzer-DcrDecoder
Expand Down
1 change: 1 addition & 0 deletions fuzz/librawspeed/decompressors/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(DECOMPRESSORS
"SamsungV2Decompressor"
"SonyArw1Decompressor"
"SonyArw2Decompressor"
"SonyArw6Decompressor"
"UncompressedDecompressor"
"VC5Decompressor"
)
Expand Down
62 changes: 62 additions & 0 deletions fuzz/librawspeed/decompressors/SonyArw6Decompressor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
RawSpeed - RAW file decoder.

Copyright (C) 2026 Kabir Kwatra

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/SonyArw6Decompressor.h"
#include "MemorySanitizer.h"
#include "common/RawImage.h"
#include "common/RawspeedException.h"
#include "fuzz/Common.h"
#include "io/Buffer.h"
#include "io/ByteStream.h"
#include "io/Endianness.h"
#include <cassert>
#include <cstdint>
#include <cstdio>

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, rawspeed::implicit_cast<rawspeed::Buffer::size_type>(Size));
const rawspeed::DataBuffer db(b, rawspeed::Endianness::little);
rawspeed::ByteStream bs(db);

rawspeed::RawImage mRaw(CreateRawImage(bs));

// The decoder feeds the active CFA dimensions; mirror that by reusing the
// image dimensions chosen above. The constructor validates type/dims.
rawspeed::SonyArw6Decompressor d(mRaw, bs.getStream(bs.getRemainSize()),
mRaw->dim.x, mRaw->dim.y);

mRaw->createData();

d.decompress();

rawspeed::MSan::CheckMemIsInitialized(
mRaw->getByteDataAsUncroppedArray2DRef());
} catch (const rawspeed::RawspeedException&) { // NOLINT(bugprone-empty-catch)
// Exceptions are good, crashes are bad.
}

return 0;
}
71 changes: 70 additions & 1 deletion src/librawspeed/decoders/ArwDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "decompressors/LJpegDecoder.h"
#include "decompressors/SonyArw1Decompressor.h"
#include "decompressors/SonyArw2Decompressor.h"
#include "decompressors/SonyArw6Decompressor.h"
#include "decompressors/UncompressedDecompressor.h"
#include "io/Buffer.h"
#include "io/ByteStream.h"
Expand Down Expand Up @@ -182,6 +183,11 @@ RawImage ArwDecoder::decodeRawInternal() {
return mRaw;
}

if (32766 == compression) {
DecodeARW6(raw);
return mRaw;
}

if (32767 != compression)
ThrowRDE("Unsupported compression %i", compression);

Expand Down Expand Up @@ -316,7 +322,7 @@ void ArwDecoder::DecodeLJpeg(const TiffIFD* raw) {
}

if (width == 0 || height == 0 || width % 2 != 0 || height % 2 != 0 ||
width > 9728 || height > 6656)
width > 10240 || height > 7168)
ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

mRaw->dim = iPoint2D(width, height);
Expand Down Expand Up @@ -412,6 +418,69 @@ void ArwDecoder::DecodeLJpeg(const TiffIFD* raw) {
mRaw->subFrame(crop);
}

void ArwDecoder::DecodeARW6(const TiffIFD* raw) {
// Sony "Compressed RAW 2" / ARW 6.0 (TIFF compression 32766), lossy RAW.
uint32_t width = raw->getEntry(TiffTag::IMAGEWIDTH)->getU32();
uint32_t height = raw->getEntry(TiffTag::IMAGELENGTH)->getU32();

// FF frames are 10016x6672, APS-C 6592x4372. Raise the dimension ceiling.
if (width == 0 || height == 0 || width % 2 != 0 || height % 2 != 0 ||
width > 10240 || height > 7168)
ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

const TiffEntry* offsets = raw->getEntry(TiffTag::STRIPOFFSETS);
const TiffEntry* counts = raw->getEntry(TiffTag::STRIPBYTECOUNTS);
if (offsets->count != 1)
ThrowRDE("Multiple Strips found: %u", offsets->count);
if (counts->count != offsets->count)
ThrowRDE("Byte count number does not match strip size: count:%u, strips:%u",
counts->count, offsets->count);

uint32_t off = offsets->getU32();
uint32_t c2 = counts->getU32();

if (!mFile.isValid(off))
ThrowRDE("Data offset after EOF, file probably truncated");
if (!mFile.isValid(off, c2))
c2 = mFile.getSize() - off;

mRaw->dim = iPoint2D(width, height);
mRaw->createData();

ByteStream input(DataBuffer(mFile.getSubView(off, c2), Endianness::little));

SonyArw6Decompressor d(mRaw, input, implicit_cast<int>(width),
implicit_cast<int>(height));
d.decompress();

// The ARW6 output is already in the final 16-bit CFA domain; no SonyCurve is
// applied for this path. Its value domain is the native ~14-bit scale, so the
// levels from cameras.xml (black 512 / white 16383) and the
// SONYBLACKLEVEL/SONYWHITELEVEL EXIF tags (read by GetWB()) apply unchanged.

// Crop to the active CFA. The decoded frame keeps the tiling overlap on its
// right edge, so the active area is narrower than the decoded width: it is
// the DefaultCrop region plus its symmetric border (DefaultCropOrigin px on
// each side), equal to the lossless path's SonyRawImageSize. Both tags are
// read from the file, so this holds for any frame size with no hard-coded
// dimensions or full-frame/APS-C special-casing.
const TiffEntry* cropOrigin = raw->getEntry(TiffTag::DEFAULTCROPORIGIN);
const TiffEntry* cropSize = raw->getEntry(TiffTag::DEFAULTCROPSIZE);
// 64-bit so the doubled origin and the sum cannot wrap a 32-bit value past
// the frame-size guard.
uint64_t activeW =
uint64_t{cropSize->getU32(0)} + (2 * cropOrigin->getU32(0));
uint64_t activeH =
uint64_t{cropSize->getU32(1)} + (2 * cropOrigin->getU32(1));
if (activeW > width || activeH > height)
ThrowRDE("Active area (%llu; %llu) exceeds the decoded frame (%u; %u)",
static_cast<unsigned long long>(activeW),
static_cast<unsigned long long>(activeH), width, height);
mRaw->subFrame(iRectangle2D(0, 0, implicit_cast<int>(activeW),
implicit_cast<int>(activeH)));
applyCrop = false;
}

void ArwDecoder::DecodeARW2(ByteStream input, uint32_t w, uint32_t h,
uint32_t bpp) {

Expand Down
1 change: 1 addition & 0 deletions src/librawspeed/decoders/ArwDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ArwDecoder final : public AbstractTiffDecoder {
RawImage decodeSRF();
void DecodeARW2(ByteStream input, uint32_t w, uint32_t h, uint32_t bpp);
void DecodeLJpeg(const TiffIFD* raw);
void DecodeARW6(const TiffIFD* raw);
void DecodeUncompressed(const TiffIFD* raw) const;
static void SonyDecrypt(Array1DRef<const uint8_t> ibuf,
Array1DRef<uint8_t> obuf, int len, uint32_t key);
Expand Down
3 changes: 3 additions & 0 deletions src/librawspeed/decompressors/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ FILE(GLOB SOURCES
"SonyArw1Decompressor.h"
"SonyArw2Decompressor.cpp"
"SonyArw2Decompressor.h"
"SonyArw6Decompressor.cpp"
"SonyArw6Decompressor.h"
"SonyArw6LogToLinear.h"
"UncompressedDecompressor.cpp"
"UncompressedDecompressor.h"
"VC5Decompressor.cpp"
Expand Down
Loading
Loading