/* Check if the decoder can decode the image from this camera */ /* A RawDecoderException will be thrown if the camera isn't supported */ /* Unknown cameras does NOT generate any specific feedback */ /* This function must be overridden by actual decoders */ void decodeUncompressed(ref TiffIFD rawIFD, BitOrder order) { UInt32 nslices = rawIFD.getEntry(STRIPOFFSETS).count; TiffEntry* offsets = rawIFD.getEntry(STRIPOFFSETS); TiffEntry* counts = rawIFD.getEntry(STRIPBYTECOUNTS); UInt32 yPerSlice = rawIFD.getEntry(ROWSPERSTRIP).getInt(); UInt32 width = rawIFD.getEntry(IMAGEWIDTH).getInt(); UInt32 height = rawIFD.getEntry(IMAGELENGTH).getInt(); UInt32 bitPerPixel = rawIFD.getEntry(BITSPERSAMPLE).getInt(); vector<RawSlice> slices; UInt32 offY = 0; for (UInt32 s = 0; s < nslices; s++) { RawSlice slice; slice.offset = offsets.getInt(s); slice.count = counts.getInt(s); if (offY + yPerSlice > height) slice.h = height - offY; else slice.h = yPerSlice; offY += yPerSlice; if (mFile.isValid(slice.offset, slice.count)) // Only decode if size is valid slices.push_back(slice); } if (0 == slices.size()) ThrowRDE("RAW Decoder: No valid slices found. File probably truncated."); mRaw.dim = iPoint2D(width, offY); mRaw.createData(); mRaw.whitePoint = (1 << bitPerPixel) - 1; offY = 0; for (UInt32 i = 0; i < slices.size(); i++) { RawSlice slice = slices[i]; ByteStream in(mFile, slice.offset, slice.count); iPoint2D size(width, slice.h); iPoint2D pos(0, offY); bitPerPixel = (int)((UInt64)((UInt64)slice.count * 8u) / (slice.h * width)); try { readUncompressedRaw(in, size, pos, width * bitPerPixel / 8, bitPerPixel, order); } catch (RawDecoderException &e) { if (i > 0) mRaw.setError(e.what()); else throw; } catch (IOException &e) {
TiffIFD(ref FileMap f, UInt32 offset, UInt32 _depth) { TIFF_DEPTH(_depth); mFile = f; ushort[] entries; entries = *(ushort*)f.getData(offset, 2); // Directory entries in this IFD for (UInt32 i = 0; i < entries; i++) { int entry_offset = (int)(offset + 2 + i * 12); // If the space for the entry is no longer valid stop reading any more as // the file is broken or truncated if (!mFile.isValid(entry_offset, 12)) break; TiffEntry t = null; try { t = new TiffEntry(f, entry_offset, offset); } catch (IOException) { // Ignore unparsable entry continue; } switch (t.tag) { case DNGPRIVATEDATA: { try { TiffIFD* maker_ifd = parseDngPrivateData(t); mSubIFD.push_back(maker_ifd); delete(t); } catch (TiffParserException) { // Unparsable private data are added as entries mEntry[t.tag] = t; } catch (IOException) { // Unparsable private data are added as entries mEntry[t.tag] = t; } } break; case MAKERNOTE: case MAKERNOTE_ALT: { try { mSubIFD.push_back(parseMakerNote(f, t.getDataOffset(), endian)); delete(t); } catch (TiffParserException) { // Unparsable makernotes are added as entries mEntry[t.tag] = t; } catch (IOException) { // Unparsable makernotes are added as entries mEntry[t.tag] = t; } } break; case FUJI_RAW_IFD: if (t.type == 0xd) // FUJI - correct type t.type = TIFF_LONG; case SUBIFDS: case EXIFIFDPOINTER: try { for (UInt32 j = 0; j < t.count; j++) { mSubIFD.push_back(new TiffIFD(f, t.getInt(j), depth)); } delete(t); } catch (TiffParserException) { // Unparsable subifds are added as entries mEntry[t.tag] = t; } catch (IOException) { // Unparsable subifds are added as entries mEntry[t.tag] = t; } break; default: mEntry[t.tag] = t; } } nextIFD = *(align1_int*)f.getData(offset + 2 + entries * 12, 4); }