コード例 #1
0
        /* Parse FUJI information */
        /* It is a simpler form of Tiff IFD, so we add them as TiffEntries */
        void ParseFuji(uint offset)
        {
            try
            {
                IFD tempIFD = new IFD(ifd.endian, ifd.Depth);
                ImageBinaryReaderBigEndian bytes = new ImageBinaryReaderBigEndian(stream, offset);
                uint entries = bytes.ReadUInt32();

                if (entries > 255)
                {
                    throw new RawDecoderException("Too many entries");
                }

                for (int i = 0; i < entries; i++)
                {
                    UInt16 tag    = bytes.ReadUInt16();
                    uint   length = bytes.ReadUInt16();
                    Tag    t;

                    // Set types of known tags
                    switch (tag)
                    {
                    case 0x100:
                    case 0x121:
                    case 0x2ff0:
                        t = new Tag((TagType)tag, TiffDataType.SHORT, length / 2);
                        for (int k = 0; k < t.dataCount; k++)
                        {
                            t.data[k] = bytes.ReadUInt16();
                        }
                        break;

                    case 0xc000:
                        // This entry seem to have swapped endianness:
                        t = new Tag((TagType)tag, TiffDataType.LONG, length / 4);
                        for (int k = 0; k < t.dataCount; k++)
                        {
                            t.data[k] = bytes.ReadUInt32();
                        }
                        break;

                    default:
                        t = new Tag((TagType)tag, TiffDataType.UNDEFINED, length);
                        for (int k = 0; k < t.dataCount; k++)
                        {
                            t.data[k] = bytes.ReadByte();
                        }
                        break;
                    }
                    tempIFD.tags.Add(t.TagId, t);
                    //bytes.ReadBytes((int)length);
                }
                ifd.subIFD.Add(tempIFD);
            }
            catch (IOException)
            {
                throw new RawDecoderException("IO error occurred during parsing. Skipping the rest");
            }
        }
コード例 #2
0
        protected void Parse(uint offset)
        {
            //parse the ifd
            if (stream.Length < 16)
            {
                throw new RawDecoderException("Not a TIFF file (size too small)");
            }
            Endianness endian = Endianness.Little;

            byte[] data = new byte[5];
            stream.Position = offset;
            stream.Read(data, 0, 4);
            if (data[0] == 0x4D || data[1] == 0x4D)
            {
                //open binaryreader
                reader = new ImageBinaryReaderBigEndian(stream);
                endian = Endianness.Big;
                if (data[3] != 42 && data[3] != 0x4f) // ORF sometimes has 0x4f!
                {
                    throw new RawDecoderException("Not a TIFF file (magic 42)");
                }
            }
            else if (data[0] == 0x49 || data[1] == 0x49)
            {
                reader = new ImageBinaryReader(stream);
                if (data[2] != 42 && data[2] != 0x52 && data[2] != 0x55) // ORF has 0x52, RW2 0x55!
                {
                    throw new RawDecoderException("Not a TIFF file (magic 42)");
                }
            }
            else
            {
                throw new RawDecoderException("Not a TIFF file (ID)");
            }
            reader.Position = offset + 4;

            var newIfd = new IFD(reader, reader.ReadUInt32(), endian, 0, (int)offset);

            if (ifd == null)
            {
                ifd = newIfd;
            }
            else
            {
                ifd.subIFD.Add(newIfd);
            }
            uint nextIFD = newIfd.NextOffset;

            while (nextIFD != 0)
            {
                ifd.subIFD.Add(new IFD(reader, nextIFD, endian, 0, (int)offset));
                if (ifd.subIFD.Count > 100)
                {
                    throw new RawDecoderException("TIFF file has too many Sub IFDs, probably broken");
                }
                nextIFD = (ifd.subIFD[ifd.subIFD.Count - 1]).NextOffset;
            }
        }
コード例 #3
0
ファイル: FujiMakerNote.cs プロジェクト: xvanneste/Raw2Jpeg
        public FujiMakerNote(byte[] data, Endianness endian, int depth) : base(endian, depth)
        {
            ImageBinaryReader file;

            if (endian == Endianness.Little)
            {
                file = new ImageBinaryReader(data);
            }
            else if (endian == Endianness.Big)
            {
                file = new ImageBinaryReaderBigEndian(data);
            }
            else
            {
                throw new RawDecoderException("Endianness not correct " + endian);
            }
            file.BaseStream.Position = 12;
            RelativeOffset           = 0;
            Parse(file);
            file.Dispose();
        }
コード例 #4
0
ファイル: PentaxMakernote.cs プロジェクト: xvanneste/Raw2Jpeg
        public PentaxMakernote(byte[] data, int offset, int parentOffset, Endianness endian, int depth) : base(endian, depth)
        {
            ImageBinaryReader buffer;

            if (data[offset] == 0x4D && data[offset + 1] == 0x4D)
            {
                buffer = new ImageBinaryReaderBigEndian(data);
            }
            else if (data[offset] == 0x49 && data[offset + 1] == 0x49)
            {
                buffer = new ImageBinaryReaderBigEndian(data);
            }
            else
            {
                throw new RawDecoderException("Makernote endianness unknown " + data[0]);
            }
            buffer.BaseStream.Position += (offset + 2);
            RelativeOffset              = -parentOffset;
            //offset are from the start of the tag
            Parse(buffer);
            buffer.Dispose();
        }
コード例 #5
0
        public NikonMakerNote(byte[] data, int depth) : base(Endianness.Little, depth)
        {
            //read the header
            // buffer.BaseStream.Position = offset;
            StringMagic = "";
            for (int i = 0; i < 6; i++)
            {
                StringMagic += (char)data[i];
            }

            Version = (ushort)(data[8] << 8 | data[7]);
            //buffer.BaseStream.Position = 2 + offset;//jump the padding
            data = data.Skip(10).ToArray();
            //header = new Header(buffer, 0); //0 car beggining of the stream
            ImageBinaryReader buffer;

            if (data[0] == 0x4D && data[1] == 0x4D)
            {
                buffer = new ImageBinaryReaderBigEndian(data);
                endian = Endianness.Big;
            }
            else if (data[0] == 0x49 && data[1] == 0x49)
            {
                buffer = new ImageBinaryReader(data);
                endian = Endianness.Little;
            }
            else
            {
                throw new RawDecoderException("Makernote endianness unknown " + data[0]);
            }
            buffer.BaseStream.Position = 2;
            buffer.ReadUInt16();
            uint TIFFoffset = buffer.ReadUInt32();

            buffer.BaseStream.Position = TIFFoffset;
            Parse(buffer);
            //parse gps info
            buffer.Dispose();
        }
コード例 #6
0
ファイル: Makernote.cs プロジェクト: xvanneste/Raw2Jpeg
        public Makernote(byte[] data, uint offset, Endianness endian, int depth, int parentOffset) : base(endian, depth)
        {
            type = IFDType.Makernote;
            ImageBinaryReader file;

            if (endian == Endianness.Little)
            {
                file = new ImageBinaryReader(data);
            }
            else if (endian == Endianness.Big)
            {
                file = new ImageBinaryReaderBigEndian(data);
            }
            else
            {
                throw new RawDecoderException("Endianness not correct " + endian);
            }

            file.BaseStream.Position = offset;
            RelativeOffset           = -parentOffset;
            Parse(file);
            file.Dispose();
        }
コード例 #7
0
        public PanasonicMakernote(byte[] data, Endianness endian, int depth) : base(endian, depth)
        {
            //start wth a tiff headder

            this.type = IFDType.Makernote;
            ImageBinaryReader file;

            if (endian == Endianness.Little)
            {
                file = new ImageBinaryReader(data);
            }
            else if (endian == Endianness.Big)
            {
                file = new ImageBinaryReaderBigEndian(data);
            }
            else
            {
                throw new RawDecoderException("Endianness not correct " + endian);
            }

            file.BaseStream.Position = 8;
            Parse(file);
            file.Dispose();
        }
コード例 #8
0
        public RAFDecoder(Stream file) : base(file, true)
        {
            //alt_layout = false;
            // FUJI has pointers to IFD's at fixed byte offsets
            // So if camera is FUJI, we cannot use ordinary TIFF parser
            //get first 8 char and see if equal fuji
            file.Position = 0;
            var data = new byte[110];

            file.Read(data, 0, 8);
            string dataAsString = System.Text.Encoding.UTF8.GetString(data.Take(8).ToArray());

            if (dataAsString != "FUJIFILM")
            {
                throw new RawDecoderException("Header is wrong");
            }
            //Fuji is indexer reverse endian
            reader = new ImageBinaryReaderBigEndian(file);
            reader.BaseStream.Position = 8;
            //read next 8 byte
            dataAsString = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(8).ToArray()).Trim();
            //4 byte version
            var version = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(4).ToArray());
            //8 bytes unknow ??
            var unknow = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(8).ToArray()).Trim();

            //32 byte a string (camera model)
            dataAsString = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(32).ToArray()).Trim();
            //Directory
            //4 bytes version
            version = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(4).ToArray());
            //20 bytes unkown ??
            dataAsString = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(20).ToArray()).Trim();

            //parse the ifd
            uint first_ifd = reader.ReadUInt32();

            relativeOffset = first_ifd + 12;
            reader.ReadInt32();
            //raw header
            // RAW information IFD on older
            uint third_ifd = reader.ReadUInt32();

            reader.ReadUInt32();
            uint secondIFD = reader.ReadUInt32();
            uint count     = reader.ReadUInt32();

            try
            {
                Parse(secondIFD);
            }
            catch (Exception)
            {
                //old format
                ifd = new IFD(Endianness.Big, 0);
                //raw image
                var entry = new Tag(TagType.FUJI_STRIPOFFSETS, TiffDataType.LONG, 1);
                entry.data[0] = secondIFD;
                ifd.tags.Add(entry.TagId, entry);
                entry         = new Tag(TagType.FUJI_STRIPBYTECOUNTS, TiffDataType.LONG, 1);
                entry.data[0] = count;
                ifd.tags.Add(entry.TagId, entry);
            }
            Parse(first_ifd + 12);
            ParseFuji(third_ifd);
        }
コード例 #9
0
        public void DecodePentax(IFD root, uint offset, uint size)
        {
            // Prepare huffmann table              0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 = 16 entries
            byte[] pentax_tree = { 0, 2, 3, 1, 1, 1, 1, 1, 1, 2,  0,  0, 0, 0, 0, 0,
                                   3, 4, 2, 5, 1, 6, 0, 7, 8, 9, 10, 11, 12 };
            //                                     0 1 2 3 4 5 6 7 8 9  0  1  2 = 13 entries

            /* Attempt to read huffman table, if found in makernote */
            Tag t = root.GetEntryRecursive((TagType)0x220);

            if (t != null)
            {
                if (t.dataType == TiffDataType.UNDEFINED)
                {
                    ImageBinaryReader stream;
                    if (root.endian == Common.GetHostEndianness())
                    {
                        stream = new ImageBinaryReader(t.GetByteArray());
                    }
                    else
                    {
                        stream = new ImageBinaryReaderBigEndian(t.GetByteArray());
                    }

                    int depth = (stream.ReadUInt16() + 12) & 0xf;

                    stream.ReadBytes(12);
                    uint[] v0 = new uint[16];
                    uint[] v1 = new uint[16];
                    uint[] v2 = new uint[16];
                    for (int i = 0; i < depth; i++)
                    {
                        v0[i] = stream.ReadUInt16();
                    }

                    for (int i = 0; i < depth; i++)
                    {
                        v1[i] = stream.ReadByte();
                    }

                    /* Reset bits */
                    for (int i = 0; i < 17; i++)
                    {
                        huff[0].bits[i] = 0;
                    }

                    /* Calculate codes and store bitcounts */
                    for (int c = 0; c < depth; c++)
                    {
                        v2[c] = v0[c] >> (int)(12 - v1[c]);
                        huff[0].bits[v1[c]]++;
                    }
                    /* Find smallest */
                    for (int i = 0; i < depth; i++)
                    {
                        uint sm_val = 0xfffffff;
                        uint sm_num = 0xff;
                        for (uint j = 0; j < depth; j++)
                        {
                            if (v2[j] <= sm_val)
                            {
                                sm_num = j;
                                sm_val = v2[j];
                            }
                        }
                        huff[0].huffval[i] = sm_num;
                        v2[sm_num]         = 0xffffffff;
                    }
                    stream.Dispose();
                }
                else
                {
                    throw new RawDecoderException("Unknown Huffman table type.");
                }
            }
            else
            {
                /* Initialize with legacy data */
                uint acc = 0;
                for (int i = 0; i < 16; i++)
                {
                    huff[0].bits[i + 1] = pentax_tree[i];
                    acc += huff[0].bits[i + 1];
                }
                huff[0].bits[0] = 0;
                for (int i = 0; i < acc; i++)
                {
                    huff[0].huffval[i] = pentax_tree[i + 16];
                }
            }
            huff[0].UseBigTable = true;
            huff[0].Create(frame.precision);

            input.BaseStream.Position = 0;
            huff[0].bitPump           = new BitPumpMSB(input, offset, size);
            int[] pUp1   = { 0, 0 };
            int[] pUp2   = { 0, 0 };
            int   pLeft1 = 0;
            int   pLeft2 = 0;

            for (int y = 0; y < raw.fullSize.dim.height; y++)
            {
                var realY = y * raw.fullSize.dim.width;
                pUp1[y & 1] += huff[0].Decode();
                pUp2[y & 1] += huff[0].Decode();
                raw.fullSize.rawView[realY]     = (ushort)(pLeft1 = pUp1[y & 1]);
                raw.fullSize.rawView[realY + 1] = (ushort)(pLeft2 = pUp2[y & 1]);
                for (int x = 2; x < raw.fullSize.dim.width; x += 2)
                {
                    pLeft1 += huff[0].Decode();
                    pLeft2 += huff[0].Decode();
                    raw.fullSize.rawView[realY + x]     = (ushort)pLeft1;
                    raw.fullSize.rawView[realY + x + 1] = (ushort)pLeft2;
                }
            }
        }