ImageTools.IO.Gif.GifDecoder.ReadFrameColors C# (CSharp) Method

ReadFrameColors() private method

private ReadFrameColors ( byte indices, byte colorTable, GifImageDescriptor descriptor ) : void
indices byte
colorTable byte
descriptor GifImageDescriptor
return void
        private void ReadFrameColors(byte[] indices, byte[] colorTable, GifImageDescriptor descriptor)
        {
            int imageWidth = _logicalScreenDescriptor.Width;
            int imageHeight = _logicalScreenDescriptor.Height;

            if (_currentFrame == null)
            {
                _currentFrame = new byte[imageWidth * imageHeight * 4];
            }

            byte[] lastFrame = null;

            if (_graphicsControl != null &&
                _graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious)
            {
                lastFrame = new byte[imageWidth * imageHeight * 4];

                Array.Copy(_currentFrame, lastFrame, lastFrame.Length);
            }

            int offset = 0, i = 0, index = -1;

            int iPass = 0; // the interlace pass
            int iInc = 8; // the interlacing line increment
            int iY = 0; // the current interlaced line
            int writeY = 0; // the target y offset to write to

            for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++)
            {
                // Check if this image is interlaced.
                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 (iY >= descriptor.Height)
                    {
                        iPass++;
                        switch (iPass)
                        {
                            case 1:
                                iY = 4;
                                break;
                            case 2:
                                iY = 2;
                                iInc = 4;
                                break;
                            case 3:
                                iY = 1;
                                iInc = 2;
                                break;
                        }
                    }

                    writeY = iY + descriptor.Top;

                    iY += iInc;
                }
                else
                {
                    writeY = y;
                }

                //TODO: review performance here

                for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++)
                {
                    offset = writeY * imageWidth + x;

                    index = indices[i];

                    if (_graphicsControl == null ||
                        _graphicsControl.TransparencyFlag == false ||
                        _graphicsControl.TransparencyIndex != index)
                    {
                        _currentFrame[offset * 4 + 0] = colorTable[index * 3 + 0];
                        _currentFrame[offset * 4 + 1] = colorTable[index * 3 + 1];
                        _currentFrame[offset * 4 + 2] = colorTable[index * 3 + 2];
                        _currentFrame[offset * 4 + 3] = (byte)255;
                    }

                    i++;
                }
            }

            byte[] pixels = new byte[imageWidth * imageHeight * 4];

            Array.Copy(_currentFrame, pixels, pixels.Length);

            SimpleImage currentImage = null;

            if (_image.Pixels == null)
            {
                currentImage = _image;
                currentImage.SetPixels(imageWidth, imageHeight, pixels);
            }
            else
            {
                SimpleImage frame = new SimpleImage();

                currentImage = frame;
                currentImage.SetPixels(imageWidth, imageHeight, pixels);

                _image.Frames.Add(frame);
            }

            if (_graphicsControl != null)
            {
                if (_graphicsControl.DelayTime > 0)
                {
                    ExtraImageInfo extraImgInfo = currentImage.ExtraImageInfo;
                    if (extraImgInfo == null)
                    {
                        currentImage.ExtraImageInfo = extraImgInfo = new ExtraImageInfo();
                    }
                    extraImgInfo.DelayTime = _graphicsControl.DelayTime;
                }

                if (_graphicsControl.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;

                            _currentFrame[offset * 4 + 0] = 0;
                            _currentFrame[offset * 4 + 1] = 0;
                            _currentFrame[offset * 4 + 2] = 0;
                            _currentFrame[offset * 4 + 3] = 0;
                        }
                    }
                }
                else if (_graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious)
                {
                    _currentFrame = lastFrame;
                }
            }
        }