Exemplo n.º 1
0
        /// <summary>
        /// Writes the pixel information to the stream.
        /// TODO: This is WHACK! We should be able to do this without creating yet another array.
        /// </summary>
        /// <param name="stream">The stream.</param>
        private void WriteDataChunks(Stream stream)
        {
            byte[] data = this.EncodePixelData();

            byte[] buffer;
            int    bufferLength;

            MemoryStream memoryStream = null;

            try
            {
                memoryStream = new MemoryStream();

                using (ZlibDeflateStream deflateStream = new ZlibDeflateStream(memoryStream, this.CompressionLevel))
                {
                    deflateStream.Write(data, 0, data.Length);
                }

                bufferLength = (int)memoryStream.Length;
                buffer       = memoryStream.ToArray();
            }
            finally
            {
                memoryStream?.Dispose();
            }

            int numChunks = bufferLength / MaxBlockSize;

            if (bufferLength % MaxBlockSize != 0)
            {
                numChunks++;
            }

            for (int i = 0; i < numChunks; i++)
            {
                int length = bufferLength - (i * MaxBlockSize);

                if (length > MaxBlockSize)
                {
                    length = MaxBlockSize;
                }

                this.WriteChunk(stream, PngChunkTypes.Data, buffer, i * MaxBlockSize, length);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Writes the pixel information to the stream.
        /// </summary>
        /// <typeparam name="TColor">The pixel format.</typeparam>
        /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
        /// <param name="pixels">The pixel accessor.</param>
        /// <param name="stream">The stream.</param>
        private void WriteDataChunks <TColor, TPacked>(PixelAccessor <TColor, TPacked> pixels, Stream stream)
            where TColor : struct, IPackedPixel <TPacked>
            where TPacked : struct, IEquatable <TPacked>
        {
            int bytesPerScanline = this.width * this.bytesPerPixel;

            byte[] previousScanline = new byte[bytesPerScanline];
            byte[] rawScanline      = new byte[bytesPerScanline];
            int    resultLength     = bytesPerScanline + 1;

            byte[] result = new byte[resultLength];

            if (this.PngColorType != PngColorType.Palette)
            {
                this.sub     = new byte[resultLength];
                this.up      = new byte[resultLength];
                this.average = new byte[resultLength];
                this.paeth   = new byte[resultLength];
            }

            byte[]       buffer;
            int          bufferLength;
            MemoryStream memoryStream = null;

            try
            {
                memoryStream = new MemoryStream();
                using (ZlibDeflateStream deflateStream = new ZlibDeflateStream(memoryStream, this.CompressionLevel))
                {
                    for (int y = 0; y < this.height; y++)
                    {
                        deflateStream.Write(this.EncodePixelRow(pixels, y, previousScanline, rawScanline, result), 0, resultLength);

                        Swap(ref rawScanline, ref previousScanline);
                    }
                }

                buffer       = memoryStream.ToArray();
                bufferLength = buffer.Length;
            }
            finally
            {
                memoryStream?.Dispose();
            }

            // Store the chunks in repeated 64k blocks.
            // This reduces the memory load for decoding the image for many decoders.
            int numChunks = bufferLength / MaxBlockSize;

            if (bufferLength % MaxBlockSize != 0)
            {
                numChunks++;
            }

            for (int i = 0; i < numChunks; i++)
            {
                int length = bufferLength - (i * MaxBlockSize);

                if (length > MaxBlockSize)
                {
                    length = MaxBlockSize;
                }

                this.WriteChunk(stream, PngChunkTypes.Data, buffer, i * MaxBlockSize, length);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Writes the pixel information to the stream.
        /// </summary>
        /// <typeparam name="TColor">The pixel format.</typeparam>
        /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
        /// <param name="pixels">The pixel accessor.</param>
        /// <param name="stream">The stream.</param>
        private void WriteDataChunks <TColor, TPacked>(PixelAccessor <TColor, TPacked> pixels, Stream stream)
            where TColor : struct, IPackedPixel <TPacked>
            where TPacked : struct
        {
            int bytesPerScanline = this.width * this.bytesPerPixel;

            byte[] previousScanline = ArrayPool <byte> .Shared.Rent(bytesPerScanline);

            byte[] rawScanline = ArrayPool <byte> .Shared.Rent(bytesPerScanline);

            int resultLength = bytesPerScanline + 1;

            byte[] result = ArrayPool <byte> .Shared.Rent(resultLength);

            byte[]       buffer;
            int          bufferLength;
            MemoryStream memoryStream = null;

            try
            {
                memoryStream = new MemoryStream();
                using (ZlibDeflateStream deflateStream = new ZlibDeflateStream(memoryStream, this.CompressionLevel))
                {
                    for (int y = 0; y < this.height; y++)
                    {
                        this.EncodePixelRow(pixels, y, previousScanline, rawScanline, result, bytesPerScanline);
                        deflateStream.Write(result, 0, resultLength);

                        // Do a bit of shuffling;
                        byte[] tmp = rawScanline;
                        rawScanline      = previousScanline;
                        previousScanline = tmp;
                    }

                    deflateStream.Flush();
                    bufferLength = (int)memoryStream.Length;
                    buffer       = memoryStream.ToArray();
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(previousScanline);

                ArrayPool <byte> .Shared.Return(rawScanline);

                ArrayPool <byte> .Shared.Return(result);

                memoryStream?.Dispose();
            }

            // Store the chunks in repeated 64k blocks.
            // This reduces the memory load for decoding the image for many decoders.
            int numChunks = bufferLength / MaxBlockSize;

            if (bufferLength % MaxBlockSize != 0)
            {
                numChunks++;
            }

            for (int i = 0; i < numChunks; i++)
            {
                int length = bufferLength - (i * MaxBlockSize);

                if (length > MaxBlockSize)
                {
                    length = MaxBlockSize;
                }

                this.WriteChunk(stream, PngChunkTypes.Data, buffer, i * MaxBlockSize, length);
            }
        }