/// <summary> /// Decodes the specified stream. /// </summary> /// <param name="stream">The stream.</param> /// <returns>This.</returns> public override FileBase Decode(Stream stream) { Header = FileHeader.Read(stream); ScreenDescriptor = LogicalScreenDescriptor.Read(stream); if (ScreenDescriptor.GlobalColorTablePresent) { ColorTable = ColorTable.Read(stream, ScreenDescriptor.GlobalColorTableSize); } var Flag = stream.ReadByte(); while (Flag != SectionTypes.Terminator) { if (Flag == SectionTypes.ImageLabel) { Frames.Add(Frame.Read(stream, ColorTable, GraphicsControlExtension, ScreenDescriptor, Frames)); } else if (Flag == SectionTypes.ExtensionIntroducer) { var Label = (SectionTypes)stream.ReadByte(); if (Label == SectionTypes.GraphicControlLabel) { GraphicsControlExtension = GraphicsControl.Read(stream); } else if (Label == SectionTypes.CommentLabel) { Comment.Read(stream); } else if (Label == SectionTypes.ApplicationExtensionLabel) { ApplicationExtension.Read(stream); } else if (Label == SectionTypes.PlainTextLabel) { PlainText.Read(stream); } } else if (Flag == SectionTypes.EndIntroducer) { break; } Flag = stream.ReadByte(); } return(this); }
/// <summary> /// Loads the animation. /// </summary> /// <param name="animation">The animation.</param> /// <param name="quantizedImage">The quantized image.</param> private void LoadAnimation(Animation animation, QuantizedImage quantizedImage) { var TempImage = animation[0]; var TransparencyIndex = quantizedImage.TransparentIndex; Header = new FileHeader(); ScreenDescriptor = new LogicalScreenDescriptor(TempImage, TransparencyIndex, BitDepth); Frames.Add(new Frame(TempImage, quantizedImage, BitDepth, animation.Delay)); if (animation.Count > 1) { AppExtension = new ApplicationExtension(animation.RepeatCount, animation.Count); for (int x = 1; x < animation.Count; ++x) { quantizedImage = Quantizer.Quantize(animation[x], Quality); TempImage = animation[x]; Frames.Add(new Frame(TempImage, quantizedImage, BitDepth, animation.Delay)); } } }
/// <summary> /// Loads the image. /// </summary> /// <param name="image">The image.</param> /// <param name="quantizedImage">The quantized image.</param> private void LoadImage(Image image, QuantizedImage quantizedImage) { Header = new FileHeader(); ScreenDescriptor = new LogicalScreenDescriptor(image, quantizedImage.TransparentIndex, BitDepth); Frames.Add(new Frame(image, quantizedImage, BitDepth, 150)); }
private static byte[] ReadFrameColors(FrameIndices indices, ColorTable colorTable, GraphicsControl graphicsControl, ImageDescriptor descriptor, LogicalScreenDescriptor screenDescriptor, List <Frame> frames) { int imageWidth = screenDescriptor.Width; int imageHeight = screenDescriptor.Height; byte[] CurrentFrame = null; byte[] LastFrame = null; if (frames.Count > 0 && graphicsControl != null && graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious) { CurrentFrame = new byte[imageWidth * imageHeight * 4]; Array.Copy(frames[frames.Count - 1].Data, CurrentFrame, CurrentFrame.Length); LastFrame = new byte[imageWidth * imageHeight * 4]; Array.Copy(CurrentFrame, LastFrame, LastFrame.Length); } else { CurrentFrame = new byte[imageWidth * imageHeight * 4]; } int offset, i = 0; int interlacePass = 0; int interlaceIncrement = 8; int interlaceY = 0; for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++) { int writeY; if (descriptor.Interlace) { if (interlaceY >= descriptor.Height) { interlacePass++; switch (interlacePass) { case 1: interlaceY = 4; break; case 2: interlaceY = 2; interlaceIncrement = 4; break; case 3: interlaceY = 1; interlaceIncrement = 2; break; } } writeY = interlaceY + descriptor.Top; interlaceY += interlaceIncrement; } else { writeY = y; } for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++) { offset = ((writeY * imageWidth) + x) * 4; int index = indices.Indices[i]; if (graphicsControl == null || graphicsControl.TransparencyFlag == false || graphicsControl.TransparencyIndex != index) { int indexOffset = index * 3; CurrentFrame[offset + 0] = colorTable.Data[indexOffset]; CurrentFrame[offset + 1] = colorTable.Data[indexOffset + 1]; CurrentFrame[offset + 2] = colorTable.Data[indexOffset + 2]; CurrentFrame[offset + 3] = 255; } i++; } } return(CurrentFrame); }
/// <summary> /// Reads from the specified stream. /// </summary> /// <param name="stream">The stream.</param> /// <param name="globalColorTable">The global color table.</param> /// <param name="graphicsControl">The graphics control.</param> /// <param name="screenDescriptor">The screen descriptor.</param> /// <param name="frames">The frames.</param> /// <returns> /// The resulting frame. /// </returns> public static Frame Read(Stream stream, ColorTable globalColorTable, GraphicsControl graphicsControl, LogicalScreenDescriptor screenDescriptor, List <Frame> frames) { var TempDescriptor = ImageDescriptor.Read(stream); ColorTable LocalColorTable = TempDescriptor.LocalColorTableExists ? ColorTable.Read(stream, TempDescriptor.LocalColorTableSize) : globalColorTable; var TempIndices = FrameIndices.Read(stream, TempDescriptor); var Data = ReadFrameColors(TempIndices, LocalColorTable, graphicsControl, TempDescriptor, screenDescriptor, frames); Skip(stream, 0); return(new Frame(graphicsControl, TempDescriptor, LocalColorTable, TempIndices, Data)); }