示例#1
0
        /// <summary>
        /// Reads the gif comments.
        /// </summary>
        private void ReadComments()
        {
            int length;

            var stringBuilder = new StringBuilder();

            while ((length = this.stream.ReadByte()) != 0)
            {
                if (length > GifConstants.MaxCommentSubBlockLength)
                {
                    GifThrowHelper.ThrowInvalidImageContentException($"Gif comment length '{length}' exceeds max '{GifConstants.MaxCommentSubBlockLength}' of a comment data block");
                }

                if (this.IgnoreMetadata)
                {
                    this.stream.Seek(length, SeekOrigin.Current);
                    continue;
                }

                using (IManagedByteBuffer commentsBuffer = this.MemoryAllocator.AllocateManagedByteBuffer(length))
                {
                    this.stream.Read(commentsBuffer.Array, 0, length);
                    string commentPart = GifConstants.Encoding.GetString(commentsBuffer.Array, 0, length);
                    stringBuilder.Append(commentPart);
                }
            }

            if (stringBuilder.Length > 0)
            {
                this.gifMetadata.Comments.Add(stringBuilder.ToString());
            }
        }
示例#2
0
        /// <summary>
        /// Reads the image descriptor.
        /// </summary>
        private void ReadImageDescriptor()
        {
            this.stream.Read(this.buffer, 0, 9);

            this.imageDescriptor = GifImageDescriptor.Parse(this.buffer);
            if (this.imageDescriptor.Height == 0 || this.imageDescriptor.Width == 0)
            {
                GifThrowHelper.ThrowInvalidImageContentException("Width or height should not be 0");
            }
        }
示例#3
0
        /// <summary>
        /// Decodes and decompresses all pixel indices from the stream.
        /// </summary>
        /// <param name="minCodeSize">Minimum code size of the data.</param>
        /// <param name="pixels">The pixel array to decode to.</param>
        public void DecodePixels(int minCodeSize, Buffer2D <byte> pixels)
        {
            // Calculate the clear code. The value of the clear code is 2 ^ minCodeSize
            int clearCode = 1 << minCodeSize;

            // It is possible to specify a larger LZW minimum code size than the palette length in bits
            // which may leave a gap in the codes where no colors are assigned.
            // http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp#lzw_compression
            if (minCodeSize < 2 || clearCode > MaxStackSize)
            {
                // Don't attempt to decode the frame indices.
                // Theoretically we could determine a min code size from the length of the provided
                // color palette but we won't bother since the image is most likely corrupted.
                GifThrowHelper.ThrowInvalidImageContentException("Gif Image does not contain a valid LZW minimum code.");
            }

            // The resulting index table length.
            int width  = pixels.Width;
            int height = pixels.Height;
            int length = width * height;

            int codeSize = minCodeSize + 1;

            // Calculate the end code
            int endCode = clearCode + 1;

            // Calculate the available code.
            int availableCode = clearCode + 2;

            // Jillzhangs Code see: http://giflib.codeplex.com/
            // Adapted from John Cristy's ImageMagick.
            int code;
            int oldCode  = NullCode;
            int codeMask = (1 << codeSize) - 1;
            int bits     = 0;

            int top   = 0;
            int count = 0;
            int bi    = 0;
            int xyz   = 0;

            int data  = 0;
            int first = 0;

            ref int prefixRef     = ref MemoryMarshal.GetReference(this.prefix.GetSpan());
示例#4
0
        /// <inheritdoc/>
        public Image <TPixel> Decode <TPixel>(Configuration configuration, Stream stream)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            var decoder = new GifDecoderCore(configuration, this);

            try
            {
                return(decoder.Decode <TPixel>(stream));
            }
            catch (InvalidMemoryOperationException ex)
            {
                Size dims = decoder.Dimensions;

                GifThrowHelper.ThrowInvalidImageContentException($"Can not decode image. Failed to allocate buffers for possibly degenerate dimensions: {dims.Width}x{dims.Height}.", ex);

                // Not reachable, as the previous statement will throw a exception.
                return(null);
            }
        }