Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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;
            }
        }