Exemple #1
0
        private byte[] ReadFrameLocalColorTable(GifImageDescriptor imageDescriptor)
        {
            byte[] localColorTable = null;

            if (imageDescriptor.LocalColorTableFlag == true)
            {
                localColorTable = new byte[imageDescriptor.LocalColorTableSize * 3];

                _stream.Read(localColorTable, 0, localColorTable.Length);
            }

            return(localColorTable);
        }
Exemple #2
0
        private GifImageDescriptor ReadImageDescriptor()
        {
            byte[] buffer = new byte[9];

            _stream.Read(buffer, 0, buffer.Length);

            byte packed = buffer[8];

            GifImageDescriptor imageDescriptor = new GifImageDescriptor();

            imageDescriptor.Left   = BitConverter.ToInt16(buffer, 0);
            imageDescriptor.Top    = BitConverter.ToInt16(buffer, 2);
            imageDescriptor.Width  = BitConverter.ToInt16(buffer, 4);
            imageDescriptor.Height = BitConverter.ToInt16(buffer, 6);
            imageDescriptor.LocalColorTableFlag = ((packed & 0x80) >> 7) == 1;
            imageDescriptor.LocalColorTableSize = 2 << (packed & 0x07);
            imageDescriptor.InterlaceFlag       = ((packed & 0x40) >> 6) == 1;

            return(imageDescriptor);
        }
Exemple #3
0
        private void ReadFrame()
        {
            GifImageDescriptor imageDescriptor = ReadImageDescriptor();

            byte[] localColorTable = ReadFrameLocalColorTable(imageDescriptor);

            byte[] indices = ReadFrameIndices(imageDescriptor);

            // Determine the color table for this frame. If there is a local one, use it
            // otherwise use the global color table.
            byte[] colorTable = localColorTable != null ? localColorTable : _globalColorTable;

            ReadFrameColors(indices, colorTable, imageDescriptor);

            int blockSize = _stream.ReadByte();

            if (blockSize > 0)
            {
                _stream.Seek(blockSize, SeekOrigin.Current);
            }
        }
Exemple #4
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];
            GifFrame frame = new GifFrame(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.SetPixelEx(x, y, new Color32(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)
                {
                    //GifFrame im = new GifFrame(imageWidth, imageHeight);
                    //im.Clear(new Color32(0,0,0,0));
                    //_image.AddFrame(im);
                    //_image.loop = false;
                }
                else if (_graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious)
                {
                    _image.loop = true;
                }
            }
        }