Exemplo n.º 1
0
    private GifImageData readImageData(GifData gifData, byte[] bytes, int offset)
    {
        GifImageData imgData        = new GifImageData(gifData);
        int          subblockOffset = offset + 1;
        int          subblockCount  = 0;

        imgData.lzwMinimumCodeSize = bytes[offset];

        // Read subblock data
        while (true)
        {
            int subblockSize = bytes[subblockOffset];

            if (subblockSize == 0)
            {
                break;
            }
            else
            {
                for (int i = 0; i < subblockSize; i++)
                {
                    imgData.blockBytes.Add(bytes[subblockOffset + 1 + i]);
                }

                subblockOffset += subblockSize + 1;
                subblockCount++;
            }
        }
        imgData.endingOffset = subblockOffset;

        //Debug.Log("Number of subblocks read: " + subblockCount);

        return(imgData);
    }
Exemplo n.º 2
0
    static void CalculColors(GifData gifData, int index)
    {
        Color[] previousFrame = gifData.previousFrame;
        if (previousFrame == null)
        {
            previousFrame = new Color[gifData.canvasWidth * gifData.canvasHeight];
        }
        Color[] currentFrame = gifData.currentFrame;
        if (currentFrame == null)
        {
            currentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight];
        }
        Color[] transparentFrame = gifData.transparentFrame;
        if (transparentFrame == null)
        {
            transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight];
        }

        GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[index];
        GifImageDescriptor          imageDescriptor    = graphicsControlExt.imageDescriptor;
        GifImageData imageData      = imageDescriptor.imageData;
        int          top            = imageDescriptor.imageTop;
        int          left           = imageDescriptor.imageLeft;
        int          disposalMethod = graphicsControlExt.disposalMethod;

        int transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1;

        Color[] colorTabel = imageData.imageDescriptor.localColorTableFlag ? imageData.imageDescriptor.localColorTable : gifData.globalColorTable;

        for (int j = 0; j < imageDescriptor.imageWidth; j++)
        {
            for (int k = 0; k < imageDescriptor.imageHeight; k++)
            {
                int x           = left + j;
                int y           = (gifData.canvasHeight - 1) - (top + k);
                int colorIndex  = imageData.colorIndices[j + k * imageDescriptor.imageWidth];
                int pixelOffset = x + y * gifData.canvasWidth;

                if (colorIndex != transparencyIndex)
                {
                    currentFrame[pixelOffset] = colorTabel[colorIndex];
                }
            }
        }

        currentFrame.CopyTo(previousFrame, 0);
        if (disposalMethod == 0 || disposalMethod == 2)
        {
            currentFrame     = new Color[currentFrame.Length];
            imageData.colors = currentFrame;
        }
        else
        {
            imageData.colors = new Color[currentFrame.Length];
            currentFrame.CopyTo(imageData.colors, 0);
        }
        gifData.previousFrame    = previousFrame;
        gifData.currentFrame     = currentFrame;
        gifData.transparentFrame = transparentFrame;
    }
Exemplo n.º 3
0
    internal static GifImageData ReadImageData(Stream stream, bool metadataOnly)
    {
        var imgData = new GifImageData();

        imgData.Read(stream, metadataOnly);
        return(imgData);
    }
Exemplo n.º 4
0
    private void Read(Stream stream, IEnumerable <GifExtension> controlExtensions, bool metadataOnly)
    {
        //Note: at this point, the Image Separator (0x2C) has already been read
        Descriptor = GifImageDescriptor.ReadImageDescriptor(stream);

        if (Descriptor.HasLocalColorTable)
        {
            LocalColorTable = GifHelpers.ReadColorTable(stream, Descriptor.LocalColorTableSize);
        }

        ImageData  = GifImageData.ReadImageData(stream, metadataOnly);
        Extensions = controlExtensions.ToList().AsReadOnly();
    }
Exemplo n.º 5
0
    static void CalculColors(GifData gifData)
    {
        Color[] previousFrame    = new Color[gifData.canvasWidth * gifData.canvasHeight];
        Color[] currentFrame     = new Color[gifData.canvasWidth * gifData.canvasHeight];
        Color[] transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight];

        // Create sprites
        for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++)
        {
            GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i];
            GifImageDescriptor          imageDescriptor    = graphicsControlExt.imageDescriptor;
            GifImageData imageData      = imageDescriptor.imageData;
            int          top            = imageDescriptor.imageTop;
            int          left           = imageDescriptor.imageLeft;
            int          disposalMethod = graphicsControlExt.disposalMethod;

            int     transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1;
            Color[] colorTabel        = imageData.imageDescriptor.localColorTableFlag ? imageData.imageDescriptor.localColorTable : gifData.globalColorTable;

            for (int j = 0; j < imageDescriptor.imageWidth; j++)
            {
                for (int k = 0; k < imageDescriptor.imageHeight; k++)
                {
                    int x           = left + j;
                    int y           = (gifData.canvasHeight - 1) - (top + k);
                    int colorIndex  = imageData.colorIndices[j + k * imageDescriptor.imageWidth];
                    int pixelOffset = x + y * gifData.canvasWidth;

                    if (colorIndex != transparencyIndex)
                    {
                        currentFrame[pixelOffset] = colorTabel[colorIndex];//imageData.getColor(colorIndex);
                    }
                }
            }
            // Set texture pixels and create sprite
            // Store current frame as previous before continuing, and reset current frame
            currentFrame.CopyTo(previousFrame, 0);
            if (disposalMethod == 0 || disposalMethod == 2)
            {
                currentFrame     = new Color[currentFrame.Length];
                imageData.colors = currentFrame;
            }
            else
            {
                imageData.colors = new Color[currentFrame.Length];
                currentFrame.CopyTo(imageData.colors, 0);
            }
        }
    }
Exemplo n.º 6
0
    static List <Texture2D> CreateAnimator(GifData gifData)
    {
        List <Texture2D> sprites = new List <Texture2D>();

        // Create sprites
        for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++)
        {
            GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i];
            GifImageDescriptor          imageDescriptor    = graphicsControlExt.imageDescriptor;
            GifImageData imageData = imageDescriptor.imageData;

            Texture2D texture = new Texture2D(gifData.canvasWidth, gifData.canvasHeight);

            // Set texture pixels and create sprite
            texture.SetPixels(imageData.colors);
            texture.Apply();
            texture.filterMode = FilterMode.Point;
            sprites.Add(texture);
        }
        return(sprites);
    }
Exemplo n.º 7
0
    public void CreateNextTexture()
    {
        if (textures == null)
        {
            textures = new List <Texture2D>();
        }
        int c = decodeCount;

        for (int i = createCount; i < c; i++)
        {
            GifGraphicsControlExtension graphicsControlExt = graphicsControlExtensions[i];
            GifImageDescriptor          imageDescriptor    = graphicsControlExt.imageDescriptor;
            GifImageData imageData = imageDescriptor.imageData;

            Texture2D texture = new Texture2D(canvasWidth, canvasHeight);
            texture.SetPixels(imageData.colors);
            texture.Apply();
            texture.filterMode = FilterMode.Point;
            textures.Add(texture);
        }
        createCount = c;
    }
Exemplo n.º 8
0
        private async Task <Stream> GetIndexStreamAsync(GifFrame frame, CancellationToken cancellationToken)
        {
            GifImageData data = frame.ImageData;

            cancellationToken.ThrowIfCancellationRequested();
            this._sourceStream.Seek(data.CompressedDataStartOffset, SeekOrigin.Begin);
            MemoryStream ms = new MemoryStream(this._indexStreamBuffer);

            try
            {
                await GifHelpers.CopyDataBlocksToStreamAsync(this._sourceStream, (Stream)ms, cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                if (ms != null)
                {
                    ((IDisposable)ms).Dispose();
                }
            }
            ms = null;
            return((Stream) new LzwDecompressStream(this._indexStreamBuffer, (int)data.LzwMinimumCodeSize));
        }
        /// <summary>
        /// Animates the given image.
        /// </summary>
        /// <param name="image"></param>
        /// <param name="onFrameChangedHandler"></param>
        public void Animate(Image image, EventHandler onFrameChangedHandler)
        {
            if (!CanAnimate(image))
            {
                return;
            }

            if (ourImageState.ContainsKey(image))
            {
                return;
            }

            // AddOrUpdate has a race condition that could allow us to erroneously
            // create multiple animation threads per image.  To combat that
            // we manually try to add entries ourself, and if it fails we
            // kill the thread.
            //
            GifImageData toAdd = AddFactory(image, onFrameChangedHandler);

            if (!ourImageState.TryAdd(image, toAdd))
            {
                Interlocked.Exchange(ref toAdd.myIsThreadDead, 1);
            }
        }
Exemplo n.º 10
0
        private GifImageData AddFactory(Image image, EventHandler eventHandler)
        {
            GifImageData data;

            lock (image) {
                data = new GifImageData(image, eventHandler);
            }

            Thread heartbeat = new Thread(() => {
                int sleepTime = getSleepAmountInMilliseconds(data.GetCurrentDelayInMilliseconds());
                Thread.Sleep(sleepTime);
                while (data.ThreadIsNotDead())
                {
                    data.HandleUpdateTick();
                    sleepTime = getSleepAmountInMilliseconds(data.GetCurrentDelayInMilliseconds());
                    Thread.Sleep(sleepTime);
                }
            });

            heartbeat.IsBackground = true;
            heartbeat.Name         = "heartbeat - HighResolutionAnimator";
            heartbeat.Start();
            return(data);
        }
Exemplo n.º 11
0
    private void createAnimator(GifData gifData)
    {
        List <Sprite>     sprites        = new List <Sprite>();
        GifAnimatorScript animatorScript = gameObject.AddComponent <GifAnimatorScript>();

        Color[] previousFrame    = new Color[gifData.canvasWidth * gifData.canvasHeight];
        Color[] currentFrame     = new Color[gifData.canvasWidth * gifData.canvasHeight];
        Color[] transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight];

        // Create sprites
        for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++)
        {
            GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i];
            GifImageDescriptor          imageDescriptor    = graphicsControlExt.imageDescriptor;
            GifImageData imageData         = imageDescriptor.imageData;
            int          top               = imageDescriptor.imageTop;
            int          left              = imageDescriptor.imageLeft;
            int          disposalMethod    = graphicsControlExt.disposalMethod;
            Texture2D    texture           = new Texture2D(gifData.canvasWidth, gifData.canvasHeight);
            int          transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1;

            // Determine base pixels
            if (i == 0)
            {
                texture.SetPixels(transparentFrame);
            }
            else
            {
                if (disposalMethod == 1)
                {
                    texture.SetPixels(previousFrame);
                }
                else if (disposalMethod == 2)
                {
                    texture.SetPixels(transparentFrame);
                }
                else if (disposalMethod == 3)
                {
                    throw new NotImplementedException("Disposal method 3 is not implemented.");
                }
            }

            // Set pixels from image data
            for (int j = 0; j < imageDescriptor.imageWidth; j++)
            {
                for (int k = 0; k < imageDescriptor.imageHeight; k++)
                {
                    int x           = left + j;
                    int y           = (gifData.canvasHeight - 1) - (top + k);
                    int colorIndex  = imageData.colorIndices[j + k * imageDescriptor.imageWidth];
                    int pixelOffset = x + y * gifData.canvasWidth;

                    if (colorIndex != transparencyIndex)
                    {
                        GifColor gifColor = imageData.getColor(colorIndex);

                        currentFrame[pixelOffset] = new Color(gifColor.r / 255f, gifColor.g / 255f, gifColor.b / 255f);
                    }
                }
            }

            // Set texture pixels and create sprite
            texture.SetPixels(currentFrame);
            texture.Apply();
            texture.filterMode = FilterMode.Point;
            sprites.Add(Sprite.Create(texture, new Rect(0f, 0f, gifData.canvasWidth, gifData.canvasHeight), new Vector2(1f, 1f)));

            // Store current frame as previous before continuing, and reset current frame
            currentFrame.CopyTo(previousFrame, 0);
            if (disposalMethod == 0 || disposalMethod == 2)
            {
                currentFrame = new Color[currentFrame.Length];
            }
        }

        // Setup animator script
        animatorScript.sprites = sprites;
    }
Exemplo n.º 12
0
    private void createAnimator(GifData gifData)
    {
        List <Sprite>     sprites        = new List <Sprite>();
        GifAnimatorScript animatorScript = gameObject.AddComponent <GifAnimatorScript>();

        Color[] previousFrame    = new Color[gifData.canvasWidth * gifData.canvasHeight];
        Color[] currentFrame     = new Color[gifData.canvasWidth * gifData.canvasHeight];
        Color[] transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight];

        // Create sprites
        for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++)
        {
            GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i];
            GifImageDescriptor          imageDescriptor    = graphicsControlExt.imageDescriptor;
            GifImageData imageData         = imageDescriptor.imageData;
            int          top               = imageDescriptor.imageTop;
            int          left              = imageDescriptor.imageLeft;
            int          disposalMethod    = graphicsControlExt.disposalMethod;
            Texture2D    texture           = new Texture2D(gifData.canvasWidth, gifData.canvasHeight);
            int          transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1;

            // Determine base pixels
            if (i == 0)
            {
                texture.SetPixels(transparentFrame);
            }
            else
            {
                if (disposalMethod == 1)
                {
                    texture.SetPixels(previousFrame);
                }
                else if (disposalMethod == 2)
                {
                    texture.SetPixels(transparentFrame);
                }
                else if (disposalMethod == 3)
                {
                    throw new NotImplementedException("Disposal method 3 is not implemented.");
                }
            }

            // Set pixels from image data
            for (int j = 0; j < imageDescriptor.imageWidth; j++)
            {
                for (int k = 0; k < imageDescriptor.imageHeight; k++)
                {
                    int x           = left + j;
                    int y           = (gifData.canvasHeight - 1) - (top + k);
                    int colorIndex  = imageData.colorIndices[j + k * imageDescriptor.imageWidth];
                    int pixelOffset = x + y * gifData.canvasWidth;

                    if (colorIndex != transparencyIndex)
                    {
                        GifColor gifColor = imageData.getColor(colorIndex);

                        currentFrame[pixelOffset] = new Color(gifColor.r / 255f, gifColor.g / 255f, gifColor.b / 255f);
                    }
                }
            }

            //float bgMax = 50f / 255;
            //var transparent = currentFrame.Where(p => p.a == 0);
            //var bgMeanSum = currentFrame.Aggregate(new float[8], (curSum, color) =>
            //{
            //    curSum[4] += color.a;
            //    ++curSum[5];

            //    if (color.a > 0)
            //    {
            //        curSum[6] += color.a;
            //        ++curSum[7];
            //    }

            //    if (color.r >= bgMax || color.g >= bgMax || color.b >= bgMax)
            //        return curSum; // We are interested on dark colors

            //    curSum[0] += color.r;
            //    curSum[1] += color.g;
            //    curSum[2] += color.b;
            //    ++curSum[3];

            //    return curSum;
            //});

            //var bgMean = new Color32(
            //    (byte)(bgMeanSum[0] * 255 / bgMeanSum[3]),
            //    (byte)(bgMeanSum[1] * 255 / bgMeanSum[3]),
            //    (byte)(bgMeanSum[2] * 255 / bgMeanSum[3]),
            //    (byte)(bgMeanSum[4] * 255 / bgMeanSum[5]));

            //Debug.Log(
            //    $"Frame {i} has transparent colors?: {transparent.Any()} || Count: {transparent.Count()} || Background: {bgMean}" +
            //    Environment.NewLine +
            //    $"Solid transparency mean (must be 255): {(byte)(bgMeanSum[6] * 255 / bgMeanSum[7])}");

            // Set texture pixels and create sprite
            texture.SetPixels(currentFrame);
            texture.Apply();
            texture.filterMode = FilterMode.Point;
            sprites.Add(Sprite.Create(texture, new Rect(0f, 0f, gifData.canvasWidth, gifData.canvasHeight), new Vector2(1f, 1f)));

            // Store current frame as previous before continuing, and reset current frame
            currentFrame.CopyTo(previousFrame, 0);
            if (disposalMethod == 0 || disposalMethod == 2)
            {
                currentFrame = new Color[currentFrame.Length];
            }
        }

        // Setup animator script
        animatorScript.sprites = sprites;
    }
 public void Set(GifGraphicsControlExtension.GraphicsControlExtension g, GifImageDescriptor.ImageDescriptor id, GifImageData.ImageData d)
 {
     GCE = g;
     desciptor = id;
     data = d;
 }