Exemplo n.º 1
0
        internal GifskiError AddFrame(IntPtr handle, uint index, string path, int delay, double lastTimestamp = 0, bool isLast = false)
        {
            if (Version.Major == 0 && Version.Minor < 9)
            {
                return(_addPngFrame(handle, index, path, (ushort)(delay / 10)));
            }

            //var aa = new FormatConvertedBitmap(path.SourceFrom(), PixelFormats.Rgb24, null, 0);

            var util = new PixelUtil(new FormatConvertedBitmap(path.SourceFrom(), PixelFormats.Rgb24, null, 0));

            util.LockBitsAndUnpad();

            var bytesPerRow = util.Width * 3; //Was ((util.Width * 24 + 31) / 32) * 3

            //if (bytesPerRow % 4 != 0)
            //    bytesPerRow += (4 - (bytesPerRow % 4));

            //Pin the buffer in order to pass the address as parameter later.
            var pinnedBuffer = GCHandle.Alloc(util.Pixels, GCHandleType.Pinned);
            var address      = pinnedBuffer.AddrOfPinnedObject();

            GifskiError result;

            if (Version > new Version(0, 10, 4))
            {
                //First frame receives the delay set of the last frame.
                result = AddFrame2Pixels(handle, index, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, index == 0 ? lastTimestamp : _timeStamp);

                _timeStamp += (delay / 1000d);
            }
            else if (Version.Major == 0 && Version.Minor >= 10)
            {
                result = AddFrame2Pixels(handle, index, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, _timeStamp);

                //As a dirty fix for Gifski 0.10.2, the last frame must be duplicated to preserve the timings.
                if (isLast)
                {
                    _timeStamp += ((delay / 1000d) / 2d);
                    result      = AddFrame2Pixels(handle, index + 1, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, _timeStamp);
                }

                //Frames can't be more than 1 second apart. TODO: Add support for dealing with this issue.
                _timeStamp += (delay / 1000d);
            }
            else
            {
                //Normal delay.
                result = AddFramePixels(handle, index, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, (ushort)delay);
            }

            //The buffer must be unpinned, to free resources.
            pinnedBuffer.Free();
            util.UnlockBitsWithoutCommit();

            return(result);
        }