예제 #1
0
        public static AseFile Parse(BinaryReader reader)
        {
            int       frameCount;
            ColorType colorType;
            var       file = ParseHeader(reader, out frameCount, out colorType);

            var layerGroups = new Stack <LayerGroup>();

            layerGroups.Push(file.Layers);
            var readLayerIndex = 0;

            IUserDataAcceptor lastUserdataAcceptor = new NoOpUserDataAcceptor();

            for (var i = 0; i < frameCount; ++i)
            {
                reader.ReadDWord(); // frameBytes
                _CheckMagicNumber(reader.ReadWord(), 0xF1FA);

                var oldChunkCount = reader.ReadWord();
                var duration      = reader.ReadWord();
                var frame         = new Frame(i, duration);
                reader.ReadBytes(2);
                var newChunkCount = reader.ReadDWord();
                var chunkCount    = (oldChunkCount == 0xFFFF) ? newChunkCount : oldChunkCount;

                for (int j = 0; j < chunkCount; ++j)
                {
                    var chunkBytes = reader.ReadDWord(); // 4
                    var chunkType  = reader.ReadWord();  // 2

                    switch (chunkType)
                    {
                    case CHUNK_LAYER:
                    {
                        // only found in the first frame. This defines the layer layout for all frames.
                        lastUserdataAcceptor = ParseLayer(file, reader, layerGroups, readLayerIndex);
                        readLayerIndex      += 1;
                        break;
                    }

                    case CHUNK_CEL:
                    {
                        lastUserdataAcceptor = ParseCel(file, colorType, reader, chunkBytes, frame);
                        break;
                    }

                    case CHUNK_FRAME_TAGS:
                    {
                        ParseFrameTags(file, reader);
                        break;
                    }

                    case CHUNK_USERDATA:
                    {
                        ParseUserData(reader, lastUserdataAcceptor);
                        break;
                    }

                    default:
                    {
                        reader.ReadBytes(chunkBytes - 6);
                        break;
                    }
                    }
                }

                file.Add(frame);
            }

            // Post process: calculate pixel alpha
            foreach (var frame in file)
            {
                foreach (var cel in frame.Cels)
                {
                    if (!cel.IsLinked)
                    {
                        var transparency = cel.Opacity * file.FindLayer(cel.LayerIndex).Opacity;
                        for (var i = 0; i < cel.ColorBuffer.Length; ++i)
                        {
                            cel.ColorBuffer[i].a *= transparency;
                        }
                    }
                }
            }

            // Post process: eliminate reference cels
            file.ResolveLinkedCels();
            return(file);
        }
예제 #2
0
        static IUserDataAcceptor ParseLayer(AseFile file,
                                            BinaryReader reader,
                                            Stack <LayerGroup> layerGroups,
                                            int readLayerIndex)
        {
            IUserDataAcceptor lastUserdataAcceptor;
            var flags = reader.ReadWord();

            var visible        = (flags & 0x1) != 0;
            var referenceLayer = (flags & 0x20) != 0;

            var layerType  = (AseLayerType)reader.ReadWord();
            var childLevel = reader.ReadWord(); // childLevel

            if ((layerGroups.Count - 1) != (childLevel))
            {
                layerGroups.Pop();
                if (layerGroups.Count == 0)
                {
                    // workaround broken files ..
                    Debug.LogWarning("Layer Structure Parsing Error.");
                    layerGroups.Push(file.Layers);
                }
            }

            reader.ReadWord();
            reader.ReadWord();

            var blendMode = (BlendMode)reader.ReadWord();
            var opacity   = reader.ReadByte() / 255.0f;

            reader.ReadBytes(3);

            var layerName = reader.ReadUTF8();
            var type      = layerName.StartsWith("@") ? LayerType.Meta : LayerType.Content;

            Debug.Log("Reading layer definition " + readLayerIndex + ", " + layerName);

            if (layerType == AseLayerType.Layer && !layerName.StartsWith("//") && !referenceLayer)
            {
                //layer.index = readLayerIndex;
                var layer = new Layer(readLayerIndex, type, layerName, visible, blendMode, opacity);
                if (layer.Type == LayerType.Meta || visible)
                {
                    MetaLayerParser.Parse(layer);
                    layerGroups.Peek().Layers.Add(layer);
                }

                lastUserdataAcceptor = layer;
            }
            else if (layerType == AseLayerType.LayerGroup)
            {
                // is a layer group.
                var layerGroup = new LayerGroup(readLayerIndex, layerName);
                MetaLayerParser.Parse(layerGroup);
                layerGroups.Peek().SubGroups.Add(layerGroup);
                layerGroups.Push(layerGroup);
                lastUserdataAcceptor = layerGroup;
            }
            else
            {
                lastUserdataAcceptor = new NoOpUserDataAcceptor();
            }

            return(lastUserdataAcceptor);
        }