Пример #1
0
            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;
                    }

                    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);
                _currentFrame = new byte[imageWidth * imageHeight * 4];
                Image frame = new Image(imageWidth, imageHeight);

                int  indx = 0;
                byte r, g, b, a;

                for (uint y = 0; y < frame.Height; y++)
                {
                    for (uint x = 0; x < frame.Width; x++)
                    {
                        r = pixels[indx];
                        indx++;
                        g = pixels[indx];
                        indx++;
                        b = pixels[indx];
                        indx++;
                        a = pixels[indx];
                        indx++;
                        frame.SetPixel(x, y, new Pixel(r, g, b, a));
                    }
                }
                pixels = null;
                System.GC.Collect();
                _image.AddFrame(frame);


                if (_graphicsControl != null)
                {
                    if (_graphicsControl.DelayTime > 0)
                    {
                        _image.TimePerFrame = _graphicsControl.DelayTime;
                    }

                    if (_graphicsControl.DisposalMethod == DisposalMethod.RestoreToBackground)
                    {
                        Image im = new Image(imageWidth, imageHeight);
                        im.Clear(new Pixel(true));
                        _image.AddFrame(im);
                        _image.Loop = false;
                    }
                    else if (_graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious)
                    {
                        _image.Loop = true;
                    }
                }
            }