/// <summary> /// Constructor /// </summary> public Gif(ushort Width, ushort Height, ushort Repeat = 0) { CanvasWidth = Width; CanvasHeight = Height; Packed.Value = 0; GlobalColorTable = new byte[0]; ApplicationExtension = new ExtensionNetscape(Repeat); }
public static Type Extract(BinaryReader Reader, out Extension Extension) { Type type = (Type)Reader.ReadByte(); switch (type) { case Type.PlainText: Extension = new ExtensionGeneric(Reader); break; //todo case Type.GraphicsControl: Extension = new ExtensionGraphicsControl(Reader); break; case Type.Comment: Extension = new ExtensionGeneric(Reader); break; //todo case Type.Application: Extension = ExtensionApplication.Extract(Reader); break; default: Extension = new ExtensionGeneric(Reader); break; } return(type); }
/// <summary> /// Reads this Gif from a Stream /// </summary> /// <param name="Stream"></param> public void Read(Stream Stream) { BinaryReader reader = new BinaryReader( Stream, Encoding.ASCII, true); ////////////////////////////////////////////// // HEADER ////////////////////////////////////////////// byte[] buffer = new byte[3]; // signature reader.Read(buffer, 0, 3); if (!buffer.SequenceEqual(Constants.SIGNATURE)) { throw new Exception("Not a GIF file"); } // version reader.Read(buffer, 0, 3); // check version if (!buffer.SequenceEqual(Constants.VERSION_89A) && !buffer.SequenceEqual(Constants.VERSION_87A)) { throw new Exception("Unsupported Version"); } ////////////////////////////////////////////// // LOGICAL SCREEN DESCRIPTOR DATA ////////////////////////////////////////////// // width & height CanvasWidth = reader.ReadUInt16(); CanvasHeight = reader.ReadUInt16(); // other data Packed.Value = reader.ReadByte(); BackgroundColorIndex = reader.ReadByte(); PixelAspectRatio = reader.ReadByte(); ////////////////////////////////////////////// // GLOBAL COLOR TABLE (OPTIONAL) ////////////////////////////////////////////// GlobalColorTable = (Packed.IsGlobalColorTable) ? reader.ReadBytes((int)Packed.ByteSizeOfColorTable) : new byte[0]; ////////////////////////////////////////////// // DYNAMIC CHUNKS (OPTIONAL, EXCEPT ONE FRAME) ////////////////////////////////////////////// ExtensionGraphicsControl lastGraphicsControl = null; while (true) { byte introducer = reader.ReadByte(); // EXTENSION if (introducer == (byte)Introducer.Extension) { // try parse it Extension extension; Extension.Type type = Extension.Extract(reader, out extension); // GraphicsControl if (type == Extension.Type.GraphicsControl) { // save it for next frame if (lastGraphicsControl == null) { lastGraphicsControl = (ExtensionGraphicsControl)extension; } // not good, we got another graphicscontrol extension // without having read a frame since then... else { // discard previous one, save this one lastGraphicsControl = (ExtensionGraphicsControl)extension; } } // Application else if (type == Extension.Type.Application) { ApplicationExtension = (ExtensionApplication)extension; } // Generic else { Extensions.Add(extension); } } // IMAGEDESCRIPTOR else if (introducer == (byte)Introducer.ImageDescriptor) { // parse frame data Frame frame = new Frame(reader); // attach the last GraphicsControl extension that was // not used yet and last read before this frame if (lastGraphicsControl != null) { frame.GraphicsControl = lastGraphicsControl; lastGraphicsControl = null; } // store frame Frames.Add(frame); } // TRAILER (PARSING SUCCESSFUL) else if (introducer == (byte)Introducer.Trailer) { break; } // UNKNOWN else { throw new Exception("Unknown Dynamic Chunk Introducer"); } } reader.Dispose(); }