Skip to content

Commit e9e3f1b

Browse files
committed
LJpeg: [full] LJpeg frame matches normal DNG tile size
This is true for all RPU samples at least, even weird 3-component ones. This seems like the missing info trivia which allows support for different LJpeg CPS layouts (e.g. the square one)
1 parent 3a250a2 commit e9e3f1b

File tree

5 files changed

+30
-6
lines changed

5 files changed

+30
-6
lines changed

fuzz/librawspeed/decompressors/LJpegDecoder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
4747
const auto offsetY = bs.getU32();
4848
const auto width = bs.getU32();
4949
const auto height = bs.getU32();
50+
const auto maxWidth = bs.getU32();
51+
const auto maxHeight = bs.getU32();
5052
const auto fixDng16Bug = bs.getU32();
5153

5254
rawspeed::LJpegDecoder j(bs, mRaw);
5355
mRaw->createData();
54-
j.decode(offsetX, offsetY, width, height, fixDng16Bug);
56+
j.decode(offsetX, offsetY, width, height,
57+
rawspeed::iPoint2D(maxWidth, maxHeight), fixDng16Bug);
5558

5659
// we can not check that all the image was initialized, because normally
5760
// LJpegDecoder decodes just some one tile/slice.

src/librawspeed/decoders/ArwDecoder.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,14 @@ void ArwDecoder::DecodeLJpeg(const TiffIFD* raw) {
385385
ByteStream(
386386
DataBuffer(mFile.getSubView(offset, length), Endianness::little)),
387387
mRaw);
388-
decoder.decode(implicit_cast<uint32_t>(tileX * tilew), tileY * tileh,
389-
implicit_cast<uint32_t>(tilew), tileh, false);
388+
auto offsetX = implicit_cast<uint32_t>(tileX * tilew);
389+
auto offsetY = tileY * tileh;
390+
auto tileWidth = implicit_cast<uint32_t>(tilew);
391+
auto tileHeight = tileh;
392+
auto maxDim = iPoint2D{implicit_cast<int>(tileWidth),
393+
implicit_cast<int>(tileHeight)};
394+
decoder.decode(offsetX, offsetY, tileWidth, tileHeight, maxDim,
395+
/*fixDng16Bug=*/false);
390396
} catch (const RawDecoderException& err) {
391397
mRaw->setError(err.what());
392398
} catch (const IOException& err) {

src/librawspeed/decompressors/AbstractDngDecompressor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ template <> void AbstractDngDecompressor::decompressThread<7>() const noexcept {
116116
Array1DRef(slices.data(), implicit_cast<int>(slices.size()))) {
117117
try {
118118
LJpegDecoder d(e.bs, mRaw);
119-
d.decode(e.offX, e.offY, e.width, e.height, mFixLjpeg);
119+
d.decode(e.offX, e.offY, e.width, e.height,
120+
iPoint2D(e.dsc.tileW, e.dsc.tileH), mFixLjpeg);
120121
} catch (const RawDecoderException& err) {
121122
mRaw->setError(err.what());
122123
} catch (const IOException& err) {

src/librawspeed/decompressors/LJpegDecoder.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ LJpegDecoder::LJpegDecoder(ByteStream bs, const RawImage& img)
6363
}
6464

6565
void LJpegDecoder::decode(uint32_t offsetX, uint32_t offsetY, uint32_t width,
66-
uint32_t height, bool fixDng16Bug_) {
66+
uint32_t height, iPoint2D maxDim_,
67+
bool fixDng16Bug_) {
6768
if (offsetX >= static_cast<unsigned>(mRaw->dim.x))
6869
ThrowRDE("X offset outside of image");
6970
if (offsetY >= static_cast<unsigned>(mRaw->dim.y))
@@ -82,11 +83,18 @@ void LJpegDecoder::decode(uint32_t offsetX, uint32_t offsetY, uint32_t width,
8283
if (width == 0 || height == 0)
8384
return; // We do not need anything from this tile.
8485

86+
if (!maxDim_.hasPositiveArea() ||
87+
implicit_cast<unsigned>(maxDim_.x) < width ||
88+
implicit_cast<unsigned>(maxDim_.y) < height)
89+
ThrowRDE("Requested tile is larger than tile's maximal dimensions");
90+
8591
offX = offsetX;
8692
offY = offsetY;
8793
w = width;
8894
h = height;
8995

96+
maxDim = maxDim_;
97+
9098
fixDng16Bug = fixDng16Bug_;
9199

92100
AbstractLJpegDecoder::decodeSOI();
@@ -120,6 +128,10 @@ Buffer::size_type LJpegDecoder::decodeScan() {
120128
const LJpegDecompressor::Frame jpegFrame = {N_COMP,
121129
iPoint2D(frame.w, frame.h)};
122130

131+
if (iPoint2D(mRaw->getCpp() * maxDim.x, maxDim.y) !=
132+
iPoint2D(N_COMP * frame.w, frame.h))
133+
ThrowRDE("LJpeg frame does not match maximal tile size");
134+
123135
int numRowsPerRestartInterval;
124136
if (numMCUsPerRestartInterval == 0) {
125137
// Restart interval not enabled, so all of the rows

src/librawspeed/decompressors/LJpegDecoder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ class LJpegDecoder final : public AbstractLJpegDecoder {
3838
uint32_t w = 0;
3939
uint32_t h = 0;
4040

41+
iPoint2D maxDim;
42+
4143
public:
4244
LJpegDecoder(ByteStream bs, const RawImage& img);
4345

4446
void decode(uint32_t offsetX, uint32_t offsetY, uint32_t width,
45-
uint32_t height, bool fixDng16Bug_);
47+
uint32_t height, iPoint2D maxDim, bool fixDng16Bug_);
4648
};
4749

4850
} // namespace rawspeed

0 commit comments

Comments
 (0)