public static FlicChunk Load(ISerializer s, int width, int height) { if (s == null) { throw new ArgumentNullException(nameof(s)); } var chunkSizeOffset = s.Offset; uint chunkSize = s.UInt32(null, 0); if ((chunkSize & 0x1) != 0) { chunkSize++; } FlicChunkType type = (FlicChunkType)s.UInt16(null, 0); // Chunk FlicChunk c = type switch { FlicChunkType.Palette8Bit => new Palette8Chunk(), FlicChunkType.DeltaWordOrientedRle => new DeltaFlcChunk(), FlicChunkType.FullByteOrientedRle => new FullByteOrientedRleChunk(width, height), FlicChunkType.FullUncompressed => new CopyChunk(), FlicChunkType.Frame => new FlicFrame(width, height), // FlicChunkType.Palette6Bit => new Palette6Chunk(), // FlicChunkType.DeltaByteOrientedRle => new DeltaFliChunk(), // FlicChunkType.BlackFrameData => new BlackFrameChunk(), // FlicChunkType.Thumbnail => new ThumbnailChunk(), _ => new UnknownChunk(type) }; // Fix export issue in Autodesk Animator if (type == FlicChunkType.FullUncompressed && width * height + ChunkHeaderSize - 2 == chunkSize) { chunkSize += 2; } chunkSize = c.LoadChunk(chunkSize - ChunkHeaderSize, s) + ChunkHeaderSize; var actualChunkSize = s.Offset - chunkSizeOffset; if (actualChunkSize - chunkSize < 4) // pad { for (long i = chunkSize - actualChunkSize; i != 0; i--) { s.UInt8(null, 0); } actualChunkSize = s.Offset - chunkSizeOffset; } ApiUtil.Assert(actualChunkSize == chunkSize); return(c); } }
public FlicFile(ISerializer s) { if (s == null) { throw new ArgumentNullException(nameof(s)); } if (s.IsWriting()) { throw new NotImplementedException("FLIC file writing not currently supported"); } long startOffset = s.Offset; Size = s.UInt32(null, 0); // Size of FLIC including this header Type = (FlicHeaderType)s.UInt16(null, 0); // File type 0xAF11, 0xAF12, 0xAF30, 0xAF44, ... Frames = s.UInt16(null, 0); // Number of frames in first segment Width = s.UInt16(null, 0); // FLIC width in pixels Height = s.UInt16(null, 0); // FLIC height in pixels Depth = s.UInt16(null, 0); // Bits per pixel (usually 8) Flags = s.UInt16(null, 0); // Set to zero or to three Speed = s.UInt32(null, 0); // Delay between frames in jiffies (1/70 s) Reserved1 = s.UInt16(null, 0); // Set to zero Created = s.UInt32(null, 0); // Date of FLIC creation (FLC only) Creator = s.UInt32(null, 0); // Serial number or compiler id (FLC only) Updated = s.UInt32(null, 0); // Date of FLIC update (FLC only) Updater = s.UInt32(null, 0); // Serial number (FLC only), see creator AspectDx = s.UInt16(null, 0); // Width of square rectangle (FLC only) AspectDy = s.UInt16(null, 0); // Height of square rectangle (FLC only) ExtFlags = s.UInt16(null, 0); // EGI: flags for specific EGI extensions KeyFrames = s.UInt16(null, 0); // EGI: key-image frequency TotalFrames = s.UInt16(null, 0); // EGI: total number of frames (segments) ReqMemory = s.UInt32(null, 0); // EGI: maximum chunk size (uncompressed) MaxRegions = s.UInt16(null, 0); // EGI: max. number of regions in a CHK_REGION chunk TranspNum = s.UInt16(null, 0); // EGI: number of transparent levels Reserved2 = s.Bytes(null, null, 24); // Set to zero OFrame1 = s.UInt32(null, 0); // Offset to frame 1 (FLC only) OFrame2 = s.UInt32(null, 0); // Offset to frame 2 (FLC only) Reserved3 = s.Bytes(null, null, 40); // Set to zero var finalOffset = startOffset + Size; while (s.Offset < finalOffset) { Chunks.Add(FlicChunk.Load(s, Width, Height)); } }