private void DecodeUncompressed(ImageBinaryReader input, uint width, uint height, long size, Endianness endian) { /* * RawDecompressor.Decode12BitRawWithControl(s, w, h, rawImage); * else if ((hints.ContainsKey("jpeg32_bitorder"))) * { * Point2D dim = new Point2D(w, h), pos = new Point2D(0, 0); * RawDecompressor.ReadUncompressedRaw(s, dim, pos, w * 12 / 8, 12, BitOrder.Jpeg32, rawImage); * } * else*/ if (size >= width * height * 2) { // We're in an unpacked raw if (endian == Endianness.Little) { RawDecompressor.Decode12BitRawUnpacked(input, new Point2D(width, height), new Point2D(), rawImage); } else { RawDecompressor.Decode12BitRawBEunpackedLeftAligned(input, new Point2D(width, height), new Point2D(), rawImage); } } else if (size >= width * height * 3 / 2) { // We're in one of those weird interlaced packed raws RawDecompressor.Decode12BitRawBEInterlaced(input, new Point2D(width, height), new Point2D(), rawImage); } else { throw new RawDecoderException("ORF Decoder: Don't know how to handle the encoding in this file\n"); } }
private void DecodeCryptedUncompressed() { var data = ifd.GetIFDsWithTag(TagType.IMAGEWIDTH); if (data.Count == 0) { throw new RawDecoderException("ARW: SRF format, couldn't find width/height"); } var raw = data[0]; var size = new Point2D(raw.GetEntry(TagType.IMAGEWIDTH).GetUInt(0), raw.GetEntry(TagType.IMAGELENGTH).GetUInt(0)); uint len = (size.Area * 2); // Constants taken from dcraw uint offtemp = 862144; uint key_off = 200896; uint head_off = 164600; // Replicate the dcraw contortions to get the "decryption" key base.reader.Position = key_off;; int offset = base.reader.ReadByte() * 4; base.reader.Position = key_off + offset; byte[] d = base.reader.ReadBytes(4); uint key = (((uint)(d[0]) << 24) | ((uint)(d[1]) << 16) | ((uint)(d[2]) << 8) | d[3]); base.reader.Position = head_off; byte[] head = base.reader.ReadBytes(40); SonyDecrypt(head, 10, key); for (int i = 26; i-- > 22;) { key = key << 8 | head[i]; } // "Decrypt" the whole image buffer in place base.reader.Position = offtemp; byte[] imageData = base.reader.ReadBytes((int)len); SonyDecrypt(imageData, len / 4, key); // And now decode as a normal 16bit raw rawImage.fullSize.dim = new Point2D(size); rawImage.Init(false); using (ImageBinaryReader reader = new ImageBinaryReader(imageData, len)) { RawDecompressor.Decode16BitRawUnpacked(reader, size, new Point2D(), rawImage); } }
void DecodeUncompressed(IFD raw) { uint width = raw.GetEntry(TagType.IMAGEWIDTH).GetUInt(0); uint height = raw.GetEntry(TagType.IMAGELENGTH).GetUInt(0); uint off = raw.GetEntry(TagType.STRIPOFFSETS).GetUInt(0); rawImage.fullSize.dim = new Point2D(width, height); rawImage.Init(false); ImageBinaryReader input = new ImageBinaryReader(reader.BaseStream, off); /* * RawDecompressor.Decode14BitRawBEunpacked(input, width, height, rawImage); */ RawDecompressor.Decode16BitRawUnpacked(input, new Point2D(width, height), new Point2D(), rawImage); }
public override void DecodeRaw() { List <IFD> data = ifd.GetIFDsWithTag(TagType.PANASONIC_STRIPOFFSET); bool isOldPanasonic = false; if (data.Count == 0) { data = ifd.GetIFDsWithTag(TagType.STRIPOFFSETS); if (data == null) { throw new RawDecoderException("No image data found"); } isOldPanasonic = true; } raw = data[0]; uint height = raw.GetEntry((TagType)3).GetUInt(0); uint width = raw.GetEntry((TagType)2).GetUInt(0); if (isOldPanasonic) { Tag offsets = raw.GetEntry(TagType.STRIPOFFSETS); if (offsets.dataCount != 1) { throw new RawDecoderException("Multiple Strips found:" + offsets.dataCount); } uint off = offsets.GetUInt(0); if (!reader.IsValid(off)) { throw new RawDecoderException("Invalid image data offset, cannot decode."); } rawImage.fullSize.dim = new Point2D(width, height); rawImage.Init(false); UInt32 size = (uint)(reader.BaseStream.Length - off); input_start = new ImageBinaryReader(stream, off); if (size >= width * height * 2) { // It's completely unpacked little-endian RawDecompressor.Decode12BitRawUnpacked(input_start, new Point2D(width, height), new Point2D(), rawImage); rawImage.fullSize.ColorDepth = 12; } else if (size >= width * height * 3 / 2) { // It's a packed format RawDecompressor.Decode12BitRawWithControl(input_start, new Point2D(width, height), new Point2D(), rawImage); rawImage.fullSize.ColorDepth = 12; } else { var colorTag = raw.GetEntry((TagType)5); if (colorTag != null) { rawImage.fullSize.ColorDepth = colorTag.GetUShort(0); } else { //try to load with 12bits colordepth } // It's using the new .RW2 decoding method load_flags = 0; DecodeRw2(); } } else { rawImage.fullSize.dim = new Point2D(width, height); rawImage.Init(false); Tag offsets = raw.GetEntry(TagType.PANASONIC_STRIPOFFSET); if (offsets.dataCount != 1) { throw new RawDecoderException("Multiple Strips found:" + offsets.dataCount); } load_flags = 0x2008; uint off = offsets.GetUInt(0); if (!reader.IsValid(off)) { throw new RawDecoderException("Invalid image data offset, cannot decode."); } input_start = new ImageBinaryReader(stream, off); DecodeRw2(); } }
public override void DecodeRaw() { List <IFD> data = ifd.GetIFDsWithTag(TagType.FUJI_STRIPOFFSETS); if (data.Count <= 0) { throw new RawDecoderException("Fuji decoder: Unable to locate raw IFD"); } IFD raw = data[0]; uint height = 0; uint width = 0; var dim = raw.GetEntry(TagType.FUJI_RAWIMAGEFULLHEIGHT); if (dim != null) { height = dim.GetUInt(0); width = raw.GetEntry(TagType.FUJI_RAWIMAGEFULLWIDTH).GetUInt(0); } else { Tag wtag = raw.GetEntryRecursive(TagType.IMAGEWIDTH); if (wtag != null) { if (wtag.dataCount < 2) { throw new RawDecoderException("Fuji decoder: Size array too small"); } height = wtag.GetUShort(0); width = wtag.GetUShort(1); } } Tag e = raw.GetEntryRecursive(TagType.FUJI_LAYOUT); if (e != null) { if (e.dataCount < 2) { throw new RawDecoderException("Fuji decoder: Layout array too small"); } byte[] layout = e.GetByteArray(); //alt_layout = !(layout[0] >> 7); } if (width <= 0 || height <= 0) { throw new RawDecoderException("RAF decoder: Unable to locate image size"); } Tag offsets = raw.GetEntry(TagType.FUJI_STRIPOFFSETS); Tag counts = raw.GetEntry(TagType.FUJI_STRIPBYTECOUNTS); if (offsets.dataCount != 1 || counts.dataCount != 1) { throw new RawDecoderException("RAF Decoder: Multiple Strips found: " + offsets.dataCount + " " + counts.dataCount); } int off = offsets.GetInt(0); int count = counts.GetInt(0); ushort bps = 12; var bpsTag = raw.GetEntryRecursive(TagType.FUJI_BITSPERSAMPLE) ?? raw.GetEntryRecursive(TagType.BITSPERSAMPLE); if (bpsTag != null) { bps = bpsTag.GetUShort(0); } else { rawImage.errors.Add("BPS not found"); } rawImage.fullSize.ColorDepth = bps; // x-trans sensors report 14bpp, but data isn't packed so read as 16bpp if (bps == 14) { bps = 16; } // Some fuji SuperCCD cameras include a second raw image next to the first one // that is identical but darker to the first. The two combined can produce // a higher dynamic range image. Right now we're ignoring it. //bool double_width = hints.ContainsKey("double_width_unpacked"); rawImage.fullSize.dim = new Point2D(width, height); rawImage.Init(false); ImageBinaryReader input = new ImageBinaryReader(stream, (uint)(off + raw.RelativeOffset)); Point2D pos = new Point2D(0, 0); if (count * 8 / (width * height) < 10) { throw new RawDecoderException("Don't know how to decode compressed images"); } else if (ifd.endian == Endianness.Big) { RawDecompressor.Decode16BitRawUnpacked(input, new Point2D(width, height), pos, rawImage); } else { // RawDecompressor.ReadUncompressedRaw(input, rawImage.raw.dim, pos, width * bps / 8, bps, BitOrder.Jpeg32, rawImage); RawDecompressor.ReadUncompressedRaw(input, new Point2D(width, height), pos, width * bps / 8, bps, BitOrder.Plain, rawImage); } }
protected void DecodeUncompressed(IFD rawIFD, BitOrder order) { uint nslices = rawIFD.GetEntry(TagType.STRIPOFFSETS).dataCount; Tag offsets = rawIFD.GetEntry(TagType.STRIPOFFSETS); Tag counts = rawIFD.GetEntry(TagType.STRIPBYTECOUNTS); if (counts.dataCount != offsets.dataCount) { throw new RawDecoderException("Byte count number does not match strip size: count:" + counts.dataCount + ", strips:" + offsets.dataCount); } uint yPerSlice = rawIFD.GetEntry(TagType.ROWSPERSTRIP).GetUInt(0); uint width = rawIFD.GetEntry(TagType.IMAGEWIDTH).GetUInt(0); uint height = rawIFD.GetEntry(TagType.IMAGELENGTH).GetUInt(0); ushort bitPerPixel = rawIFD.GetEntry(TagType.BITSPERSAMPLE).GetUShort(0); rawImage.fullSize.ColorDepth = bitPerPixel; uint offY = 0; List <RawSlice> slices = new List <RawSlice>(); for (int s = 0; s < nslices; s++) { RawSlice slice = new RawSlice() { offset = offsets.GetUInt(s), count = counts.GetUInt(s), offsetY = offY }; if (offY + yPerSlice > height) { slice.h = height - offY; } else { slice.h = yPerSlice; } offY += yPerSlice; if (reader.IsValid(slice.offset, slice.count)) // Only decode if size is valid { slices.Add(slice); } } if (0 == slices.Count) { throw new RawDecoderException("RAW Decoder: No valid slices found. File probably truncated."); } rawImage.fullSize.dim = new Point2D(width, offY); rawImage.whitePoint = (ushort)((1 << bitPerPixel) - 1); offY = 0; for (int i = 0; i < slices.Count; i++) { RawSlice slice = slices[i]; reader.BaseStream.Position = slice.offset; bitPerPixel = (ushort)(slice.count * 8u / (slice.h * width)); RawDecompressor.ReadUncompressedRaw(reader, new Point2D(width, slice.h), new Point2D(0, slice.offsetY), rawImage.fullSize.cpp * width * bitPerPixel / 8, bitPerPixel, order, rawImage); offY += slice.h; } }