예제 #1
0
        public void ParseAtoms(ContainerVisitor visitor, BinaryReader reader, long offset, long stopAt, StructInstance parent)
        {
            while (offset < stopAt)
            {
                reader.BaseStream.Seek(offset, SeekOrigin.Begin);

                uint atomSize = Util.EndianFlip32(reader.ReadUInt32());
                string atomType = Util.ReadFourCC(reader);

                if (_atomDefs.ContainsKey(atomType))
                {
                    StructElement atomDef = _atomDefs[atomType];

                    StructInstance inst = GetAtomInstance(reader, atomDef, atomSize, parent);
                    string desc = GetAtomDesc(atomDef, atomSize, inst);
                    visitor.BeginVisitNode(atomType, desc);

                    // If it is a container atom
                    if (atomDef != null && atomDef.Elements == null)
                    {
                        // parse children atoms recursively
                        ParseAtoms(visitor, reader, reader.BaseStream.Position, offset + atomSize, inst);
                    }

                    if (parent != null)
                    {
                        parent[atomType] = inst;
                    }

                    visitor.EndVisitNode();
                }

                // now set offset to next atom (or end-of-file) in special case
                // (atomSize = 0 means atom goes to EOF)
                if (atomSize == 0)
                {
                    offset = reader.BaseStream.Length;
                }
                else
                {
                    offset += atomSize;
                }

                // if a 'udta' container atom, then jump ahead 4 to work around
                // Apple's QT 1.0 workaround
                // @see http://developer.apple.com/technotes/qt/qt_03.html
                if (atomType == "udta")
                {
                    offset += 4;
                }
            }
        }
예제 #2
0
        public void ParseListsChunks(ContainerVisitor visitor, BinaryReader reader, long offset, long stopAt, StructInstance parent)
        {
            while (offset < stopAt)
            {
                reader.BaseStream.Seek(offset, SeekOrigin.Begin);

                string id = Util.ReadFourCC(reader);
                int size = reader.ReadInt32();
                if (size % 2 != 0)
                {
                    size++;
                }

                StructInstance inst = null;

                if (id == "LIST") // 'LIST' listSize listType listData
                {
                    string listType = Util.ReadFourCC(reader);

                    // a LIST instance is needed to maintain a list of sub LISTs and CHUNKs.
                    StructElement listDef = _chunkDefs["LIST"];
                    inst = GetChunkInstance(reader, listDef, 0, parent);

                    if (listType != "movi")
                    {
                        visitor.BeginVisitNode(
                            string.Format("LIST ({0})", listType), string.Empty);

                        ParseListsChunks(visitor, reader, reader.BaseStream.Position, offset + size + 8, inst);
                    }
                    else
                    {
                        visitor.BeginVisitNode(
                            string.Format("LIST ({0})", listType), "Content in this list is skipped.");
                    }

                    offset += size + 8;
                }
                else // ckID ckSize ckData
                {
                    StructElement chunkDef = _chunkDefs[id];
                    inst = GetChunkInstance(reader, chunkDef, size, parent);

                    visitor.BeginVisitNode(id, GetChunkDescription(reader, id, size, inst));

                    offset += size + 8;
                }

                if (parent != null)
                {
                    // link CHUNK to its parent LIST
                    parent[id] = inst;
                }

                visitor.EndVisitNode();
            }
        }
예제 #3
0
        public void Walk(ContainerVisitor visitor)
        {
            using (BinaryReader reader = new BinaryReader(File.OpenRead(_fname)))
            {
                // 'RIFF' fileSize fileType (data)
                if (Util.ReadFourCC(reader) == "RIFF")
                {
                    _fileSize = reader.ReadInt32();
                    _fileType = Util.ReadFourCC(reader);

                    visitor.BeginVisitNode(string.Format("RIFF ({0})", _fileType), string.Empty);

                    ParseListsChunks(visitor, reader, reader.BaseStream.Position, _fileSize + 8, null);

                    visitor.EndVisitNode();
                }
            }
        }