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); }
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); }