public static AseChunk ReadChunk(AseFrame frame, ChunkType type, int size, AseReader reader) { var pos = reader.Position; AseChunk chunk = null; switch (type) { // Chunk types we care about case ChunkType.Palette: chunk = new AsePaletteChunk(frame, reader); break; case ChunkType.Layer: chunk = new AseLayerChunk(frame, reader); break; case ChunkType.Cel: chunk = new AseCelChunk(frame, reader, size); break; case ChunkType.ColorProfile: chunk = new AseColorProfileChunk(frame, reader); break; case ChunkType.FrameTags: chunk = new AseFrameTagsChunk(frame, reader); break; case ChunkType.Slice: chunk = new AseSliceChunk(frame, reader); break; case ChunkType.UserData: chunk = new AseUserDataChunk(frame, reader); break; // Chunk types we don't care about case ChunkType.OldPalette: chunk = new AseDummyChunk(frame, reader, type, size); break; // Chunk types we haven't handled yet. Indicates a bug that should be fixed. default: chunk = new AseDummyChunk(frame, reader, type, size); Debug.LogErrorFormat("Unhandled chunk type: {0}", ((ushort)type).ToString("X4")); break; } // Check that we read the right amount of bytes Assert.IsTrue((reader.Position - pos) == size, string.Format("Chunk {0} read {1} bytes but we were expected {2} bytes read", type, reader.Position - pos, size)); reader.LastChunk = chunk; return(chunk); }
public AseCelChunk(AseFrame frame, AseReader reader, int size) : base(frame) { // Keep track of read position var pos = reader.Position; LayerIndex = reader.ReadWORD(); PositionX = reader.ReadSHORT(); PositionY = reader.ReadSHORT(); Opacity = reader.ReadBYTE(); CelType = (CelType)reader.ReadWORD(); // Ignore next 7 bytes reader.ReadBYTEs(7); if (CelType == CelType.Raw) { Width = reader.ReadWORD(); Height = reader.ReadWORD(); var bytesRead = reader.Position - pos; PixelBytes = reader.ReadBYTEs(size - bytesRead); } else if (CelType == CelType.Linked) { FramePositionLink = reader.ReadWORD(); // Get a reference to our linked cell. It should be in a previous frame with a matching layer index. Debug.Assert(Frame.AseFile.Frames.Count > FramePositionLink); LinkedCel = Frame.AseFile.Frames[FramePositionLink].Chunks.OfType <AseCelChunk>().FirstOrDefault(c => c.LayerIndex == LayerIndex); Debug.Assert(LinkedCel != null); } else if (CelType == CelType.CompressedImage) { Width = reader.ReadWORD(); Height = reader.ReadWORD(); var bytesRead = reader.Position - pos; var compressed = reader.ReadBYTEs(size - bytesRead); PixelBytes = ZlibDeflate(compressed); } }
public void VisitCelChunk(AseCelChunk cel) { // Is our layer visible? var layer = m_Layers[cel.LayerIndex]; if (!layer.IsVisible) { return; } if (cel.LinkedCel != null) { cel = cel.LinkedCel; } byte opacity = PixmanCombine.MUL_UN8(cel.Opacity, layer.Opacity); var blendfunc = GetBlendFunc(layer); for (int i = 0; i < cel.Width; i++) { for (int j = 0; j < cel.Height; j++) { var x = cel.PositionX + i; var y = FlipY(cel.PositionY + j); Color32 colorBackdrop = m_Texture2D.GetPixel(x, y); Color32 colorSrc = GetPixelFromBytes(i, j, cel.Width, cel.PixelBytes); uint backdrop = Color32ToRGBA(colorBackdrop); uint src = Color32ToRGBA(colorSrc); uint result = blendfunc(backdrop, src, opacity); Color32 colorResult = RGBAToColor32(result); m_Texture2D.SetPixel(x, y, colorResult); } } m_Texture2D.Apply(); }