Esempio n. 1
0
        /* 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 */
        public void decodeUncompressed(ref IFD rawIFD, BitOrder order)
        {
            UInt32 nslices     = rawIFD.getEntry(TagType.STRIPOFFSETS).dataCount;
            Tag    offsets     = rawIFD.getEntry(TagType.STRIPOFFSETS);
            Tag    counts      = rawIFD.getEntry(TagType.STRIPBYTECOUNTS);
            UInt32 yPerSlice   = rawIFD.getEntry(TagType.ROWSPERSTRIP).getUInt();
            Int32  width       = rawIFD.getEntry(TagType.IMAGEWIDTH).getInt();
            UInt32 height      = rawIFD.getEntry(TagType.IMAGELENGTH).getUInt();
            int    bitPerPixel = rawIFD.getEntry(TagType.BITSPERSAMPLE).getInt();

            List <RawSlice> slices = new List <RawSlice>();
            UInt32          offY   = 0;

            for (UInt32 s = 0; s < nslices; s++)
            {
                RawSlice slice = new RawSlice()
                {
                    offset = (uint)offsets.data[s],
                    count  = (uint)counts.data[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.Add(slice);
                }
            }

            if (0 == slices.Count)
            {
                throw new RawDecoderException("RAW Decoder: No valid slices found. File probably truncated.");
            }

            mRaw.dim.x      = width;
            mRaw.dim.y      = (int)offY;
            mRaw.whitePoint = (uint)(1 << bitPerPixel) - 1;

            offY = 0;
            for (int i = 0; i < slices.Count; i++)
            {
                RawSlice         slice  = slices[i];
                var              stream = mFile.BaseStream;
                TIFFBinaryReader input;
                if (mFile is TIFFBinaryReaderRE)
                {
                    input = new TIFFBinaryReaderRE(mFile.BaseStream, slice.offset, slice.count);
                }
                else
                {
                    input = new TIFFBinaryReader(mFile.BaseStream, slice.offset, slice.count);
                }
                iPoint2D size = new iPoint2D(width, (int)slice.h);
                iPoint2D pos  = new iPoint2D(0, (int)offY);
                bitPerPixel = (int)(slice.count * 8u / (slice.h * width));
                try
                {
                    readUncompressedRaw(ref input, size, pos, width * bitPerPixel / 8, bitPerPixel, order);
                }
                catch (RawDecoderException)
                {
                    if (i > 0)
                    {
                        //TODO add something
                    }

                    else
                    {
                        throw;
                    }
                }
                catch (IOException e)
                {
                    if (i > 0)
                    {
                        //TODO add something
                    }

                    else
                    {
                        throw new RawDecoderException("RAW decoder: IO error occurred in first slice, unable to decode more. Error is: " + e);
                    }
                }
                offY += slice.h;
            }
        }
Esempio n. 2
0
        /* This will attempt to parse makernotes and return it as an IFD */
        IFD parseMakerNote(TIFFBinaryReader reader, uint off, Endianness parent_end)
        {
            IFD              maker_ifd = null;
            uint             offset    = 0;
            TIFFBinaryReader mFile     = null;

            reader.Position = off;
            byte[] data = reader.ReadBytes(100);
            // Pentax makernote starts with AOC\0 - If it's there, skip it
            if (data[0] == 0x41 && data[1] == 0x4f && data[2] == 0x43 && data[3] == 0)
            {
                //data = data.Skip(4).ToArray();
                offset += 4;
            }

            // Pentax also has "PENTAX" at the start, makernote starts at 8
            if (data[0 + offset] == 0x50 && data[1 + offset] == 0x45 &&
                data[2 + offset] == 0x4e && data[3 + offset] == 0x54 && data[4 + offset] == 0x41 && data[5 + offset] == 0x58)
            {
                mFile      = new TIFFBinaryReader(reader.BaseStream, offset + off, (uint)data.Length);
                parent_end = getTiffEndianness(data.Skip(8).ToArray());
                if (parent_end == Endianness.unknown)
                {
                    throw new TiffParserException("Cannot determine Pentax makernote endianness");
                }
                //data = data.Skip(10).ToArray();
                offset += 10;
                // Check for fuji signature in else block so we don't accidentally leak FileMap
            }
            else if (Common.memcmp(ref fuji_signature, ref data))
            {
                offset = 12;
                mFile  = new TIFFBinaryReader(reader.BaseStream, offset + off, (uint)data.Length);
            }
            else if (Common.memcmp(ref nikon_v3_signature, ref data))
            {
                //offset = 10;
                offset = 10;
                // Read endianness
                if (data[0 + offset] == 0x49 && data[1 + offset] == 0x49)
                {
                    parent_end = Endianness.little;
                    mFile      = new TIFFBinaryReader(reader.BaseStream, offset + off, (uint)data.Length);
                    offset     = 8;
                }
                else if (data[0 + offset] == 0x4D && data[1 + offset] == 0x4D)
                {
                    parent_end = Endianness.big;
                    mFile      = new TIFFBinaryReaderRE(reader.BaseStream, offset + off, (uint)data.Length);
                    offset     = 8;
                }
            }

            // Panasonic has the word Exif at byte 6, a complete Tiff header starts at byte 12
            // This TIFF is 0 offset based
            if (data[6] == 0x45 && data[7] == 0x78 && data[8] == 0x69 && data[9] == 0x66)
            {
                parent_end = getTiffEndianness(data.Skip(12).ToArray());
                if (parent_end == Endianness.unknown)
                {
                    throw new TiffParserException("Cannot determine Panasonic makernote endianness");
                }
                offset = 20;
            }

            // Some have MM or II to indicate endianness - read that
            if (data[0] == 0x49 && data[1] == 0x49)
            {
                offset    += 2;
                parent_end = Endianness.little;
            }
            else if (data[0] == 0x4D && data[1] == 0x4D)
            {
                parent_end = Endianness.big;
                offset    += 2;
            }

            // Olympus starts the makernote with their own name, sometimes truncated
            if (Common.strncmp(data, "OLYMP", 5))
            {
                offset += 8;
                if (Common.strncmp(data, "OLYMPUS", 7))
                {
                    offset += 4;
                }
            }

            // Epson starts the makernote with its own name
            if (Common.strncmp(data, "EPSON", 5))
            {
                offset += 8;
            }

            // Attempt to parse the rest as an IFD
            try
            {
                if (mFile == null)
                {
                    if (parent_end == Endianness.little)
                    {
                        mFile = new TIFFBinaryReader(reader.BaseStream, offset + off, (uint)data.Length);
                    }
                    else if (parent_end == Endianness.big)
                    {
                        mFile = new TIFFBinaryReaderRE(reader.BaseStream, offset + off, (uint)data.Length);
                    }
                }

                /* if (parent_end == getHostEndianness())
                 *   maker_ifd = new IFD(mFile, offset, depth);
                 * else
                 *   maker_ifd = new IFDBE(mFile, offset, depth);*/
                maker_ifd = new IFD(mFile, offset, endian, depth);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                return(null);
            }
            // If the structure cannot be read, a TiffParserException will be thrown.

            return(maker_ifd);
        }