RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
ArwDecoder.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5 Copyright (C) 2014 Pedro CĂ´rte-Real
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#include "decoders/ArwDecoder.h"
23#include "adt/Array1DRef.h"
24#include "adt/Array2DRef.h"
25#include "adt/Casts.h"
26#include "adt/Invariant.h"
27#include "adt/NORangesSet.h"
28#include "adt/Point.h"
30#include "common/Common.h"
31#include "common/RawImage.h"
38#include "io/Buffer.h"
39#include "io/ByteStream.h"
40#include "io/Endianness.h"
41#include "io/IOException.h"
42#include "metadata/Camera.h"
44#include "tiff/TiffEntry.h"
45#include "tiff/TiffIFD.h"
46#include "tiff/TiffTag.h"
47#include <array>
48#include <cassert>
49#include <cinttypes>
50#include <cstdint>
51#include <cstring>
52#include <memory>
53#include <string>
54#include <vector>
55
56using std::vector;
57
58namespace rawspeed {
59
61 [[maybe_unused]] Buffer file) {
62 const auto id = rootIFD->getID();
63 const std::string& make = id.make;
64
65 // FIXME: magic
66
67 return make == "SONY";
68}
69
71 const TiffIFD* raw = mRootIFD->getIFDWithTag(TiffTag::IMAGEWIDTH);
72
75
76 if (width == 0 || height == 0 || width > 3360 || height > 2460)
77 ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);
78
79 uint32_t len = width * height * 2;
80
81 // Constants taken from dcraw
82 uint32_t off = 862144;
83 uint32_t key_off = 200896;
84 uint32_t head_off = 164600;
85
86 // Replicate the dcraw contortions to get the "decryption" key
87 uint8_t offset = mFile[key_off];
88 const Buffer keyData = mFile.getSubView(key_off + (4 * offset), 4);
89 uint32_t key = getU32BE(keyData.begin());
90
91 static const size_t head_size = 40;
92 const auto head_orig =
93 mFile.getSubView(head_off, head_size).getAsArray1DRef();
94 vector<uint8_t> head(head_size);
95 SonyDecrypt(head_orig, {head.data(), head_size}, head_size / 4, key);
96 for (int i = 26; i > 22; i--)
97 key = key << 8 | head[i - 1];
98
99 // "Decrypt" the whole image buffer
100 const auto image_data = mFile.getSubView(off, len).getAsArray1DRef();
101 std::vector<uint8_t> image_decoded(len);
102 SonyDecrypt(image_data, {image_decoded.data(), implicit_cast<int>(len)},
103 len / 4, key);
104
105 Buffer di(image_decoded.data(), len);
106
107 // And now decode as a normal 16bit raw
108 mRaw->dim = iPoint2D(width, height);
109
111 ByteStream(DataBuffer(di.getSubView(0, len), Endianness::little)), mRaw,
112 iRectangle2D({0, 0}, iPoint2D(width, height)), 2 * width, 16,
114 mRaw->createData();
115 u.readUncompressedRaw();
116
117 return mRaw;
118}
119
121 if (const TiffEntry* model = mRootIFD->getEntryRecursive(TiffTag::MODEL);
122 model && model->getString() == "DSLR-A100") {
123 // We've caught the elusive A100 in the wild, a transitional format
124 // between the simple sanity of the MRW custom format and the wordly
125 // wonderfullness of the Tiff-based ARW format, let's shoot from the hip
126 const TiffIFD* raw = mRootIFD->getIFDWithTag(TiffTag::SUBIFDS);
128 uint32_t width = 3881;
129 uint32_t height = 2608;
130
131 mRaw->dim = iPoint2D(width, height);
132
133 ByteStream input(DataBuffer(mFile.getSubView(off), Endianness::little));
135 mRaw->createData();
136 a.decompress(input);
137
138 return mRaw;
139 }
140
141 if (hints.contains("srf_format"))
142 return decodeSRF();
143
144 ThrowRDE("No image data found");
145}
146
147std::vector<uint16_t> ArwDecoder::decodeCurve(const TiffIFD* raw) {
148 std::vector<uint16_t> curve(0x4001);
149 const TiffEntry* c = raw->getEntry(TiffTag::SONYCURVE);
150 std::array<uint32_t, 6> sony_curve = {{0, 0, 0, 0, 0, 4095}};
151
152 for (uint32_t i = 0; i < 4; i++)
153 sony_curve[i + 1] = (c->getU16(i) >> 2) & 0xfff;
154
155 for (uint32_t i = 0; i < 0x4001; i++)
156 curve[i] = implicit_cast<uint16_t>(i);
157
158 for (uint32_t i = 0; i < 5; i++)
159 for (uint32_t j = sony_curve[i] + 1; j <= sony_curve[i + 1]; j++)
160 curve[j] = implicit_cast<uint16_t>(curve[j - 1] + (1 << i));
161
162 return curve;
163}
164
166 vector<const TiffIFD*> data = mRootIFD->getIFDsWithTag(TiffTag::STRIPOFFSETS);
167
168 if (data.empty())
169 return decodeTransitionalArw();
170
171 const TiffIFD* raw = data[0];
172 int compression = raw->getEntry(TiffTag::COMPRESSION)->getU32();
173 if (1 == compression) {
175 return mRaw;
176 }
177
178 if (7 == compression) {
179 DecodeLJpeg(raw);
180 // cropping of lossless compressed L files already done in Ljpeg decoder
181 applyCrop = false;
182 return mRaw;
183 }
184
185 if (32767 != compression)
186 ThrowRDE("Unsupported compression %i", compression);
187
188 const TiffEntry* offsets = raw->getEntry(TiffTag::STRIPOFFSETS);
189 const TiffEntry* counts = raw->getEntry(TiffTag::STRIPBYTECOUNTS);
190
191 if (offsets->count != 1) {
192 ThrowRDE("Multiple Strips found: %u", offsets->count);
193 }
194 if (counts->count != offsets->count) {
195 ThrowRDE(
196 "Byte count number does not match strip size: count:%u, strips:%u ",
197 counts->count, offsets->count);
198 }
201 uint32_t bitPerPixel = raw->getEntry(TiffTag::BITSPERSAMPLE)->getU32();
202
203 switch (bitPerPixel) {
204 case 8:
205 case 12:
206 case 14:
207 break;
208 default:
209 ThrowRDE("Unexpected bits per pixel: %u", bitPerPixel);
210 }
211
212 // Sony E-550 marks compressed 8bpp ARW with 12 bit per pixel
213 // this makes the compression detect it as a ARW v1.
214 // This camera has however another MAKER entry, so we MAY be able
215 // to detect it this way in the future.
216 data = mRootIFD->getIFDsWithTag(TiffTag::MAKE);
217 if (data.size() > 1) {
218 for (auto& i : data) {
219 std::string make = i->getEntry(TiffTag::MAKE)->getString();
220 /* Check for maker "SONY" without spaces */
221 if (make == "SONY")
222 bitPerPixel = 8;
223 }
224 }
225
226 if (width == 0 || height == 0 || height % 2 != 0 || width > 9600 ||
227 height > 6376)
228 ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);
229
230 bool arw1 = uint64_t(counts->getU32()) * 8 != width * height * bitPerPixel;
231 if (arw1)
232 height += 8;
233
234 mRaw->dim = iPoint2D(width, height);
235
236 std::vector<uint16_t> curve = decodeCurve(raw);
237
238 RawImageCurveGuard curveHandler(&mRaw, curve, uncorrectedRawValues);
239
240 uint32_t c2 = counts->getU32();
241 uint32_t off = offsets->getU32();
242
243 if (!mFile.isValid(off))
244 ThrowRDE("Data offset after EOF, file probably truncated");
245
246 if (!mFile.isValid(off, c2))
247 c2 = mFile.getSize() - off;
248
249 ByteStream input(DataBuffer(mFile.getSubView(off, c2), Endianness::little));
250
251 if (arw1) {
253 mRaw->createData();
254 a.decompress(input);
256 } else {
257 DecodeARW2(input, width, height, bitPerPixel);
258 }
259
260 if (bitPerPixel == 12)
262
263 return mRaw;
264}
265
271
272 mRaw->dim = iPoint2D(width, height);
273
274 if (width == 0 || height == 0 || width > 9600 || height > 6376)
275 ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);
276
277 if (c2 == 0)
278 ThrowRDE("Strip is empty, nothing to decode!");
279
280 const Buffer buf(mFile.getSubView(off, c2));
281
282 if (hints.contains("sr2_format")) {
284 mRaw,
285 iRectangle2D({0, 0}, iPoint2D(width, height)),
286 2 * width, 16, BitOrder::MSB);
287 mRaw->createData();
288 u.readUncompressedRaw();
289 } else {
291 mRaw,
292 iRectangle2D({0, 0}, iPoint2D(width, height)),
293 2 * width, 16, BitOrder::LSB);
294 mRaw->createData();
295 u.readUncompressedRaw();
296 }
297}
298
302 uint32_t bitPerPixel = raw->getEntry(TiffTag::BITSPERSAMPLE)->getU32();
303 uint32_t photometric =
305
306 if (photometric != 32803)
307 ThrowRDE("Unsupported photometric interpretation: %u", photometric);
308
309 switch (bitPerPixel) {
310 case 8:
311 case 12:
312 case 14:
313 break;
314 default:
315 ThrowRDE("Unexpected bits per pixel: %u", bitPerPixel);
316 }
317
318 if (width == 0 || height == 0 || width % 2 != 0 || height % 2 != 0 ||
319 width > 9728 || height > 6656)
320 ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);
321
322 mRaw->dim = iPoint2D(width, height);
323
324 auto tilew = uint64_t(raw->getEntry(TiffTag::TILEWIDTH)->getU32());
326
327 if (tilew <= 0 || tileh <= 0 || tileh % 2 != 0)
328 ThrowRDE("Invalid tile size: (%" PRIu64 ", %u)", tilew, tileh);
329
330 assert(tilew > 0);
331 const auto tilesX =
333 if (!tilesX)
334 ThrowRDE("Zero tiles horizontally");
335
336 assert(tileh > 0);
337 const auto tilesY =
339 if (!tilesY)
340 ThrowRDE("Zero tiles vertically");
341
342 // Math thoughs: if we know that the total size is 100, while tile size is 11,
343 // we end up with 9 full tiles, and 1 partial tile (10 total).
344 //
345 // BUT! If we know that the total size is 100, and we have same 10 tiles,
346 // we'd naively guess that each tile's size is 10, and not 11...
347
348 const TiffEntry* offsets = raw->getEntry(TiffTag::TILEOFFSETS);
349 const TiffEntry* counts = raw->getEntry(TiffTag::TILEBYTECOUNTS);
350 if (offsets->count != counts->count) {
351 ThrowRDE("Tile count mismatch: offsets:%u count:%u", offsets->count,
352 counts->count);
353 }
354
355 // tilesX * tilesY may overflow, but division is fine, so let's do that.
356 if ((offsets->count / tilesX != tilesY || (offsets->count % tilesX != 0)) ||
357 (offsets->count / tilesY != tilesX || (offsets->count % tilesY != 0))) {
358 ThrowRDE("Tile X/Y count mismatch: total:%u X:%u, Y:%u", offsets->count,
359 tilesX, tilesY);
360 }
361
362 NORangesSet<Buffer> tilesLegality;
363 for (int tile = 0U; tile < implicit_cast<int>(offsets->count); tile++) {
364 const uint32_t offset = offsets->getU32(tile);
365 const uint32_t length = counts->getU32(tile);
366 if (!tilesLegality.insert(mFile.getSubView(offset, length)))
367 ThrowRDE("Two tiles overlap. Raw corrupt!");
368 }
369
370 mRaw->createData();
371#ifdef HAVE_OPENMP
372#pragma omp parallel for schedule(static) default(none) \
373 shared(offsets, counts) firstprivate(tilesX, tilew, tileh)
374#endif
375 for (int tile = 0U; tile < static_cast<int>(offsets->count); tile++) {
376 try {
377 const uint32_t tileX = tile % tilesX;
378 const uint32_t tileY = tile / tilesX;
379 const uint32_t offset = offsets->getU32(tile);
380 const uint32_t length = counts->getU32(tile);
381
382 LJpegDecoder decoder(
384 DataBuffer(mFile.getSubView(offset, length), Endianness::little)),
385 mRaw);
386 auto offsetX = implicit_cast<uint32_t>(tileX * tilew);
387 auto offsetY = tileY * tileh;
388 auto tileWidth = implicit_cast<uint32_t>(tilew);
389 auto tileHeight = tileh;
390 auto maxDim = iPoint2D{implicit_cast<int>(tileWidth),
391 implicit_cast<int>(tileHeight)};
392 decoder.decode(offsetX, offsetY, tileWidth, tileHeight, maxDim,
393 /*fixDng16Bug=*/false);
394 } catch (const RawDecoderException& err) {
395 mRaw->setError(err.what());
396 } catch (const IOException& err) {
397 mRaw->setError(err.what());
398 } catch (...) {
399 // We should not get any other exception type here.
400 __builtin_unreachable();
401 }
402 }
403
404 std::string firstErr;
405 if (mRaw->isTooManyErrors(1, &firstErr)) {
406 ThrowRDE("Too many errors encountered. Giving up. First Error:\n%s",
407 firstErr.c_str());
408 }
409
410 const TiffEntry* size_entry = raw->getEntry(TiffTag::SONYRAWIMAGESIZE);
411 iRectangle2D crop(0, 0, size_entry->getU32(0), size_entry->getU32(1));
412 mRaw->subFrame(crop);
413}
414
416 uint32_t bpp) {
417
418 if (bpp == 8) {
419 SonyArw2Decompressor a2(mRaw, input);
420 mRaw->createData();
421 a2.decompress();
422 return;
423 } // End bpp = 8
424
425 if (bpp == 12) {
428 iRectangle2D({0, 0}, iPoint2D(w, h)),
429 bpp * w / 8, bpp, BitOrder::LSB);
430 mRaw->createData();
431 u.readUncompressedRaw();
432
433 // Shift scales, since black and white are the same as compressed precision
434 mShiftDownScale = 2;
435 return;
436 }
437 ThrowRDE("Unsupported bit depth");
438}
439
441 if (!mRootIFD->hasEntryRecursive(TiffTag::DNGPRIVATEDATA))
442 return;
443
444 // only contains the offset, not the length!
445 const TiffEntry* priv = mRootIFD->getEntryRecursive(TiffTag::DNGPRIVATEDATA);
446 ByteStream bs = priv->getData();
448 const uint32_t off = bs.getU32();
449
450 bs = ByteStream(DataBuffer(mFile.getSubView(off), Endianness::little));
451
452 // MRW style, see MrwDecoder
453
455 uint32_t tag = bs.getU32();
456 if (0x4D5249 != tag) // MRI
457 ThrowRDE("Can not parse DNGPRIVATEDATA, invalid tag (0x%x).", tag);
458
460 uint32_t len = bs.getU32();
461
462 bs = bs.getSubStream(bs.getPosition(), len);
463
464 while (bs.getRemainSize() > 0) {
466 tag = bs.getU32();
468 len = bs.getU32();
469 (void)bs.check(len);
470 if (!len)
471 ThrowRDE("Found entry of zero length, corrupt.");
472
473 if (0x574247 != tag) { // WBG
474 // not the tag we are interested in, skip
475 bs.skipBytes(len);
476 continue;
477 }
478
479 bs.skipBytes(4);
480
482 std::array<uint16_t, 4> tmp;
483 for (auto& coeff : tmp)
484 coeff = bs.getU16();
485
486 std::array<float, 4> wbCoeffs = {};
487 wbCoeffs[0] = static_cast<float>(tmp[0]);
488 wbCoeffs[1] = static_cast<float>(tmp[1]);
489 wbCoeffs[2] = static_cast<float>(tmp[3]);
490 mRaw->metadata.wbCoeffs = wbCoeffs;
491
492 // only need this one block, no need to process any further
493 break;
494 }
495}
496
498 // Default
499 int iso = 0;
500
501 mRaw->cfa.setCFA(iPoint2D(2, 2), CFAColor::RED, CFAColor::GREEN,
503
504 if (mRootIFD->hasEntryRecursive(TiffTag::ISOSPEEDRATINGS))
505 iso = mRootIFD->getEntryRecursive(TiffTag::ISOSPEEDRATINGS)->getU32();
506
507 auto id = mRootIFD->getID();
508
509 setMetaData(meta, id, "", iso);
510 if (mRaw->whitePoint)
511 mRaw->whitePoint = *mRaw->whitePoint >> mShiftDownScale;
512 mRaw->blackLevel >>= mShiftDownScale;
513
514 // Set the whitebalance
515 try {
516 if (id.model == "DSLR-A100") { // Handle the MRW style WB of the A100
517 ParseA100WB();
518 } else { // Everything else but the A100
519 GetWB();
520 }
521 } catch (const RawspeedException& e) {
522 mRaw->setError(e.what());
523 // We caught an exception reading WB, just ignore it
524 }
525}
526
528 Array1DRef<uint8_t> obuf, int len, uint32_t key) {
529 invariant(ibuf.size() == obuf.size());
530 invariant(ibuf.size() == 4 * len);
531 invariant(obuf.size() == 4 * len);
532
533 if (0 == len)
534 return;
535
536 std::array<uint32_t, 128> pad;
537
538 // Initialize the decryption pad from the key
539 for (int p = 0; p < 4; p++)
540 pad[p] = key = uint32_t((key * 48828125UL) + 1UL);
541 pad[3] = pad[3] << 1 | (pad[0] ^ pad[2]) >> 31;
542 for (int p = 4; p < 127; p++)
543 pad[p] = (pad[p - 4] ^ pad[p - 2]) << 1 | (pad[p - 3] ^ pad[p - 1]) >> 31;
544 for (int p = 0; p < 127; p++)
545 pad[p] = getU32BE(&pad[p]);
546
547 int p = 127;
548 // Decrypt the buffer in place using the pad
549 for (int i = 0; i != len; ++i) {
550 pad[p & 127] = pad[(p + 1) & 127] ^ pad[(p + 1 + 64) & 127];
551
552 uint32_t pv = pad[p & 127];
553
554 uint32_t bv;
555 memcpy(&bv, ibuf.getBlock(4, i).begin(), sizeof(uint32_t));
556
557 bv ^= pv;
558
559 memcpy(obuf.getBlock(4, i).begin(), &bv, sizeof(uint32_t));
560
561 p++;
562 }
563}
564
565void ArwDecoder::GetWB() const {
566 // Set the whitebalance for all the modern ARW formats (everything after A100)
567 if (mRootIFD->hasEntryRecursive(TiffTag::DNGPRIVATEDATA)) {
568 NORangesSet<Buffer> ifds_undecoded;
569
570 const TiffEntry* priv =
571 mRootIFD->getEntryRecursive(TiffTag::DNGPRIVATEDATA);
572 TiffRootIFD makerNoteIFD(nullptr, &ifds_undecoded, priv->getRootIfdData(),
573 priv->getU32());
574
575 const TiffEntry* sony_offset =
577 const TiffEntry* sony_length =
579 const TiffEntry* sony_key =
581 if (!sony_offset || !sony_length || !sony_key || sony_key->count != 4)
582 ThrowRDE("couldn't find the correct metadata for WB decoding");
583
584 assert(sony_offset != nullptr);
585 uint32_t off = sony_offset->getU32();
586
587 assert(sony_length != nullptr);
588 // The Decryption is done in blocks of 4 bytes.
589 auto len = implicit_cast<uint32_t>(roundDown(sony_length->getU32(), 4));
590 if (!len)
591 ThrowRDE("No buffer to decrypt?");
592
593 assert(sony_key != nullptr);
594 uint32_t key = getU32LE(sony_key->getData().getData(4));
595
596 // "Decrypt" IFD
597 const auto& ifd_crypt = priv->getRootIfdData();
598 const auto EncryptedBuffer =
599 ifd_crypt.getSubView(off, len).getAsArray1DRef();
600 // We do have to prepend 'off' padding, because TIFF uses absolute offsets.
601 const auto DecryptedBufferSize = off + EncryptedBuffer.size();
602 std::vector<uint8_t> DecryptedBuffer(DecryptedBufferSize);
603
604 SonyDecrypt(EncryptedBuffer,
605 {&DecryptedBuffer[off], implicit_cast<int>(len)}, len / 4, key);
606
607 NORangesSet<Buffer> ifds_decoded;
608 Buffer decIFD(DecryptedBuffer.data(), DecryptedBufferSize);
609 const Buffer Padding(decIFD.getSubView(0, off));
610 // The Decrypted Root Ifd can not point to preceding padding buffer.
611 ifds_decoded.insert(Padding);
612
613 DataBuffer dbIDD(decIFD, priv->getRootIfdData().getByteOrder());
614 TiffRootIFD encryptedIFD(nullptr, &ifds_decoded, dbIDD, off);
615
616 if (encryptedIFD.hasEntry(TiffTag::SONYGRBGLEVELS)) {
617 const TiffEntry* wb = encryptedIFD.getEntry(TiffTag::SONYGRBGLEVELS);
618 if (wb->count != 4)
619 ThrowRDE("WB has %u entries instead of 4", wb->count);
620 std::array<float, 4> wbCoeffs = {};
621 wbCoeffs[0] = wb->getFloat(1);
622 wbCoeffs[1] = wb->getFloat(0);
623 wbCoeffs[2] = wb->getFloat(2);
624 mRaw->metadata.wbCoeffs = wbCoeffs;
625 } else if (encryptedIFD.hasEntry(TiffTag::SONYRGGBLEVELS)) {
626 const TiffEntry* wb = encryptedIFD.getEntry(TiffTag::SONYRGGBLEVELS);
627 if (wb->count != 4)
628 ThrowRDE("WB has %u entries instead of 4", wb->count);
629 std::array<float, 4> wbCoeffs = {};
630 wbCoeffs[0] = wb->getFloat(0);
631 wbCoeffs[1] = wb->getFloat(1);
632 wbCoeffs[2] = wb->getFloat(3);
633 mRaw->metadata.wbCoeffs = wbCoeffs;
634 }
635
636 if (encryptedIFD.hasEntry(TiffTag::SONYBLACKLEVEL)) {
637 const TiffEntry* bl = encryptedIFD.getEntry(TiffTag::SONYBLACKLEVEL);
638 if (bl->count != 4)
639 ThrowRDE("Black Level has %u entries instead of 4", bl->count);
640 mRaw->blackLevelSeparate =
641 Array2DRef(mRaw->blackLevelSeparateStorage.data(), 2, 2);
642 auto blackLevelSeparate1D = *mRaw->blackLevelSeparate->getAsArray1DRef();
643 for (int i = 0; i < 4; ++i)
644 blackLevelSeparate1D(i) = bl->getU16(i) >> mShiftDownScaleForExif;
645 }
646
647 if (encryptedIFD.hasEntry(TiffTag::SONYWHITELEVEL)) {
648 const TiffEntry* wl = encryptedIFD.getEntry(TiffTag::SONYWHITELEVEL);
649 if (wl->count != 1 && wl->count != 3)
650 ThrowRDE("White Level has %u entries instead of 1 or 3", wl->count);
651 mRaw->whitePoint = wl->getU16(0) >> mShiftDownScaleForExif;
652 }
653 }
654}
655
656} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
#define ThrowRDE(...)
assert(dim.area() >=area)
void setMetaData(const CameraMetaData *meta, const TiffID &id, const std::string &mode, int iso_speed)
CroppedArray1DRef< T > getBlock(int numElts, int index) const
Definition Array1DRef.h:122
int RAWSPEED_READONLY size() const
void decodeMetaDataInternal(const CameraMetaData *meta) override
void DecodeARW2(ByteStream input, uint32_t w, uint32_t h, uint32_t bpp)
static std::vector< uint16_t > decodeCurve(const TiffIFD *raw)
static void SonyDecrypt(Array1DRef< const uint8_t > ibuf, Array1DRef< uint8_t > obuf, int len, uint32_t key)
RawImage decodeTransitionalArw()
RawImage decodeRawInternal() override
void ParseA100WB() const
void DecodeUncompressed(const TiffIFD *raw) const
void DecodeLJpeg(const TiffIFD *raw)
static bool isAppropriateDecoder(const TiffRootIFD *rootIFD, Buffer file)
Array1DRef< const uint8_t > getAsArray1DRef() const
Definition Buffer.h:70
Buffer getSubView(size_type offset, size_type size_) const
Definition Buffer.h:78
const uint8_t * begin() const
Definition Buffer.h:99
size_type check(size_type bytes) const
Definition ByteStream.h:63
size_type RAWSPEED_READONLY getRemainSize() const
Definition ByteStream.h:87
const uint8_t * getData(size_type count)
Definition ByteStream.h:95
ByteStream getSubStream(size_type offset, size_type size_) const
Definition ByteStream.h:54
void skipBytes(size_type nbytes)
Definition ByteStream.h:130
size_type getPosition() const
Definition ByteStream.h:78
Endianness getByteOrder() const
Definition Buffer.h:154
Endianness setByteOrder(Endianness endianness_)
Definition Buffer.h:156
void decode(uint32_t offsetX, uint32_t offsetY, uint32_t width, uint32_t height, iPoint2D maxDim, bool fixDng16Bug_)
bool insert(const T &newElt)
Definition NORangesSet.h:61
void decompress(ByteStream input) const
Definition TiffEntry.h:62
DataBuffer getRootIfdData() const
float getFloat(uint32_t index=0) const
uint32_t getU32(uint32_t index=0) const
ByteStream getData() const
Definition TiffEntry.h:129
uint32_t count
Definition TiffEntry.h:84
uint16_t getU16(uint32_t index=0) const
TiffEntry *RAWSPEED_READONLY getEntryRecursive(TiffTag tag) const
Definition TiffIFD.cpp:246
bool RAWSPEED_READONLY hasEntry(TiffTag tag) const
Definition TiffIFD.h:119
TiffEntry * getEntry(TiffTag tag) const
Definition TiffIFD.cpp:313
TiffID getID() const
Definition TiffIFD.cpp:325
constexpr uint64_t RAWSPEED_READNONE roundUpDivisionSafe(uint64_t value, uint64_t div)
Definition Common.h:145
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
constexpr uint64_t RAWSPEED_READNONE roundDown(uint64_t value, uint64_t multiple)
Definition Common.h:129
Array2DRef(Array1DRef< T > data, int width, int height, int pitch) -> Array2DRef< T >
void RAWSPEED_UNLIKELY_FUNCTION RAWSPEED_NOINLINE static char buf[bufSize]
@ PHOTOMETRICINTERPRETATION
Definition TiffTag.h:46
uint32_t getU32LE(const void *data)
Definition Endianness.h:127
uint32_t getU32BE(const void *data)
Definition Endianness.h:126
std::string make
Definition TiffIFD.h:134