public void parse(iRiffChunk chunk) { if (chunk.parentTag == ACON && chunk.tag == ANIH) { header = chunk.read <ANIHeader>(); if (header.cbSizeOf != Marshal.SizeOf <ANIHeader>()) { throw new ArgumentException("ANI header has wrong size"); } frames = new Frame[header.cFrames]; return; } if (chunk.parentTag == FRAM && chunk.tag == ICON) { if (null == frames) { throw new ArgumentException("ANI header not found"); } if (chunk.index >= frames.Length) { throw new ArgumentException("Too many frames in the ANI"); } frames[chunk.index] = new Frame(chunk); parsedFrames = chunk.index + 1; return; } }
/// <summary>Parse stream with *.ani file, extract all the metadata.</summary> public AniFile(Stream stream) { Parser p = new Parser(); RiffParser.parse(stream, p.parse); if (null == p.frames || p.parsedFrames != p.frames.Length) { throw new ArgumentException("The stream is not an animated cursor file"); } header = p.header; frames = p.frames; if (frames.Length <= 0) { throw new ArgumentException("The animated cursor doesn’t have any frames"); } ICONDIRECTORY[] images = frames[0].images; formats = new ImageFormat[images.Length]; Span <ulong> vals = stackalloc ulong[images.Length]; Span <uint> bmpFormats = stackalloc uint[images.Length]; for (int i = 0; i < images.Length; i++) { uint bmp = frames[0].payloads[i].BitmapHeaderSize; vals[i] = headerValues(ref images[i]); formats[i] = new ImageFormat(ref images[i], bmp); bmpFormats[i] = bmp; } for (int i = 1; i < frames.Length; i++) { images = frames[i].images; for (int j = 0; j < vals.Length; j++) { ulong vv = headerValues(ref images[j]); uint bmp = frames[i].payloads[j].BitmapHeaderSize; if (vv != vals[j] || bmp != bmpFormats[j]) { throw new ArgumentException("Different frames of the animation use different image format, this is not supported"); } } } }