private void ReadFrameColors(byte[] indices, byte[] colorTable, GifImageDescriptor descriptor) { int imageWidth = logicalScreenDescriptor.Width; int imageHeight = logicalScreenDescriptor.Height; if (currentFrame == null){ currentFrame = new Color2[imageWidth*imageHeight]; } Color2[] lastFrame = null; if (graphicsControlExtension != null && graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious){ lastFrame = new Color2[imageWidth*imageHeight]; Array.Copy(currentFrame, lastFrame, lastFrame.Length); } int offset, i = 0; int interlacePass = 0; // The interlace pass int interlaceIncrement = 8; // The interlacing line increment int interlaceY = 0; // The current interlaced line for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++){ // Check if this image is interlaced. int writeY; // the target y offset to write to if (descriptor.InterlaceFlag){ // If so then we read lines at predetermined offsets. // When an entire image height worth of offset lines has been read we consider this a pass. // With each pass the number of offset lines changes and the starting line changes. 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; int index = indices[i]; if (graphicsControlExtension == null || graphicsControlExtension.TransparencyFlag == false || graphicsControlExtension.TransparencyIndex != index){ // Stored in r-> g-> b-> a order. int indexOffset = index*3; Color2 pixel = Color2.FromArgb(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2]); currentFrame[offset] = pixel; } i++; } } Color2[] pixels = new Color2[imageWidth*imageHeight]; Array.Copy(currentFrame, pixels, pixels.Length); ImageBase currentImage; if (decodedImage.Pixels == null){ currentImage = decodedImage; currentImage.SetPixels(imageWidth, imageHeight, pixels); currentImage.Quality = colorTable.Length/3; if (graphicsControlExtension != null && graphicsControlExtension.DelayTime > 0){ decodedImage.FrameDelay = graphicsControlExtension.DelayTime; } } else{ ImageFrame frame = new ImageFrame(); currentImage = frame; currentImage.SetPixels(imageWidth, imageHeight, pixels); currentImage.Quality = colorTable.Length/3; if (graphicsControlExtension != null && graphicsControlExtension.DelayTime > 0){ currentImage.FrameDelay = graphicsControlExtension.DelayTime; } decodedImage.Frames.Add(frame); } if (graphicsControlExtension != null){ if (graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToBackground){ for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++){ for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++){ offset = (y*imageWidth) + x; // Stored in r-> g-> b-> a order. currentFrame[offset] = default(Color2); } } } else if (graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious){ currentFrame = lastFrame; } } }
private byte[] ReadFrameLocalColorTable(GifImageDescriptor imageDescriptor) { byte[] localColorTable = null; if (imageDescriptor.LocalColorTableFlag){ localColorTable = new byte[imageDescriptor.LocalColorTableSize*3]; currentStream.Read(localColorTable, 0, localColorTable.Length); } return localColorTable; }
private GifImageDescriptor ReadImageDescriptor() { byte[] buffer = new byte[9]; currentStream.Read(buffer, 0, buffer.Length); byte packed = buffer[8]; GifImageDescriptor imageDescriptor = new GifImageDescriptor{ Left = BitConverter.ToInt16(buffer, 0), Top = BitConverter.ToInt16(buffer, 2), Width = BitConverter.ToInt16(buffer, 4), Height = BitConverter.ToInt16(buffer, 6), LocalColorTableFlag = ((packed & 0x80) >> 7) == 1, LocalColorTableSize = 2 << (packed & 0x07), InterlaceFlag = ((packed & 0x40) >> 6) == 1 }; return imageDescriptor; }
private byte[] ReadFrameIndices(GifImageDescriptor imageDescriptor) { int dataSize = currentStream.ReadByte(); LzwDecoder lzwDecoder = new LzwDecoder(currentStream); byte[] indices = lzwDecoder.DecodePixels(imageDescriptor.Width, imageDescriptor.Height, dataSize); return indices; }