| 54 | } |
| 55 | |
| 56 | RawImage SrwDecoder::decodeRawInternal() { |
| 57 | const auto* raw = mRootIFD->getIFDWithTag(STRIPOFFSETS); |
| 58 | |
| 59 | int compression = raw->getEntry(COMPRESSION)->getU32(); |
| 60 | const int bits = raw->getEntry(BITSPERSAMPLE)->getU32(); |
| 61 | |
| 62 | if (12 != bits && 14 != bits) |
| 63 | ThrowRDE("Unsupported bits per sample"); |
| 64 | |
| 65 | if (32769 != compression && 32770 != compression && 32772 != compression && 32773 != compression) |
| 66 | ThrowRDE("Unsupported compression"); |
| 67 | |
| 68 | uint32_t nslices = raw->getEntry(STRIPOFFSETS)->count; |
| 69 | if (nslices != 1) |
| 70 | ThrowRDE("Only one slice supported, found %u", nslices); |
| 71 | |
| 72 | const auto wrongComp = |
| 73 | 32770 == compression && !raw->hasEntry(static_cast<TiffTag>(40976)); |
| 74 | if (32769 == compression || wrongComp) { |
| 75 | bool bit_order = hints.get("msb_override", wrongComp ? bits == 12 : false); |
| 76 | this->decodeUncompressed(raw, bit_order ? BitOrder_MSB : BitOrder_LSB); |
| 77 | return mRaw; |
| 78 | } |
| 79 | |
| 80 | const uint32_t width = raw->getEntry(IMAGEWIDTH)->getU32(); |
| 81 | const uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); |
| 82 | mRaw->dim = iPoint2D(width, height); |
| 83 | |
| 84 | if (32770 == compression) |
| 85 | { |
| 86 | const TiffEntry* sliceOffsets = raw->getEntry(static_cast<TiffTag>(40976)); |
| 87 | if (sliceOffsets->type != TIFF_LONG || sliceOffsets->count != 1) |
| 88 | ThrowRDE("Entry 40976 is corrupt"); |
| 89 | |
| 90 | ByteStream bso(DataBuffer(*mFile, Endianness::little)); |
| 91 | bso.skipBytes(sliceOffsets->getU32()); |
| 92 | bso = bso.getStream(height, 4); |
| 93 | |
| 94 | const uint32_t offset = raw->getEntry(STRIPOFFSETS)->getU32(); |
| 95 | const uint32_t count = raw->getEntry(STRIPBYTECOUNTS)->getU32(); |
| 96 | Buffer rbuf(mFile->getSubView(offset, count)); |
| 97 | ByteStream bsr(DataBuffer(rbuf, Endianness::little)); |
| 98 | |
| 99 | SamsungV0Decompressor s0(mRaw, bso, bsr); |
| 100 | |
| 101 | mRaw->createData(); |
| 102 | |
| 103 | s0.decompress(); |
| 104 | |
| 105 | return mRaw; |
| 106 | } |
| 107 | if (32772 == compression) |
| 108 | { |
| 109 | uint32_t offset = raw->getEntry(STRIPOFFSETS)->getU32(); |
| 110 | uint32_t count = raw->getEntry(STRIPBYTECOUNTS)->getU32(); |
| 111 | const ByteStream bs( |
| 112 | DataBuffer(mFile->getSubView(offset, count), Endianness::little)); |
| 113 |
nothing calls this directly
no test coverage detected