A special stream deflating or compressing the bytes that are written to it. It uses a Deflater to perform actual deflating.
Authors of the original java version : Tom Tromey, Jochen Hoenicke
Inheritance: Stream
Esempio n. 1
0
        /**
         * Write the image data into the pngBytes array.
         * This will write one or more PNG "IDAT" chunks. In order
         * to conserve memory, this method grabs as many rows as will
         * fit into 32K bytes, or the whole image; whichever is less.
         *
         *
         * @return true if no errors; false if error grabbing pixels
         */
        protected bool WriteImageData()
        {
            int rowsLeft = height;  // number of rows remaining to write
            int startRow = 0;       // starting row to process this time through
            int nRows;              // how many rows to grab at a time

            byte[] scanLines;       // the scan lines to be compressed
            int scanPos;            // where we are in the scan lines
            int startPos;           // where this line's actual pixels start (used for filtering)

            byte[] compressedLines; // the resultant compressed lines
            int nCompressed;        // how big is the compressed area?

            //int depth;              // color depth ( handle only 8 or 32 )

            bytesPerPixel = (encodeAlpha) ? 4 : 3;

            Deflater scrunch = new Deflater(compressionLevel);
            MemoryStream outBytes = new MemoryStream(1024);

            DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);
            try {
                while (rowsLeft > 0) {
                    nRows = Math.Min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
                    nRows = Math.Max(nRows, 1);

                    int[] pixels = new int[width * nRows];
                    Array.Copy(this.pixelData, width * startRow, pixels, 0, width * nRows);

                    /*
                     * Create a data chunk. scanLines adds "nRows" for
                     * the filter bytes.
                     */
                    scanLines = new byte[width * nRows * bytesPerPixel + nRows];

                    if (filter == FILTER_SUB) {
                        leftBytes = new byte[16];
                    }
                    if (filter == FILTER_UP) {
                        priorRow = new byte[width * bytesPerPixel];
                    }

                    scanPos = 0;
                    startPos = 1;
                    for (int i = 0; i < width * nRows; i++) {
                        if (i % width == 0) {
                            scanLines[scanPos++] = (byte) filter;
                            startPos = scanPos;
                        }
                        scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
                        scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
                        scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
                        if (encodeAlpha) {
                            scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff);
                        }
                        if ((i % width == width - 1) && (filter != FILTER_NONE)) {
                            if (filter == FILTER_SUB) {
                                FilterSub(scanLines, startPos, width);
                            }
                            if (filter == FILTER_UP) {
                                FilterUp(scanLines, startPos, width);
                            }
                        }
                    }

                    /*
                     * Write these lines to the output area
                     */
                    compBytes.Write(scanLines, 0, scanPos);

                    startRow += nRows;
                    rowsLeft -= nRows;
                }
                compBytes.Close();

                /*
                 * Write the compressed bytes
                 */
                compressedLines = outBytes.ToArray();
                nCompressed = compressedLines.Length;

                crc.Reset();
                bytePos = WriteInt4(nCompressed, bytePos);
                bytePos = WriteBytes(IDAT, bytePos);
                crc.Update(IDAT);
                bytePos = WriteBytes(compressedLines, nCompressed, bytePos);
                crc.Update(compressedLines, 0, nCompressed);

                crcValue = crc.Value;
                bytePos = WriteInt4((int) crcValue, bytePos);
                scrunch.Finish();
                return true;
            } catch {
                return false;
            }
        }
Esempio n. 2
0
        /**
         * Write the image data into the pngBytes array.
         * This will write one or more PNG "IDAT" chunks. In order
         * to conserve memory, this method grabs as many rows as will
         * fit into 32K bytes, or the whole image; whichever is less.
         *
         *
         * @return true if no errors; false if error grabbing pixels
         */
        protected bool WriteImageData()
        {
            int rowsLeft = height;              // number of rows remaining to write
            int startRow = 0;                   // starting row to process this time through
            int nRows;                          // how many rows to grab at a time

            byte[] scanLines;                   // the scan lines to be compressed
            int    scanPos;                     // where we are in the scan lines
            int    startPos;                    // where this line's actual pixels start (used for filtering)

            byte[] compressedLines;             // the resultant compressed lines
            int    nCompressed;                 // how big is the compressed area?

            //int depth;              // color depth ( handle only 8 or 32 )

            bytesPerPixel = (encodeAlpha) ? 4 : 3;

            Deflater     scrunch  = new Deflater(compressionLevel);
            MemoryStream outBytes = new MemoryStream(1024);

            DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);

            try {
                while (rowsLeft > 0)
                {
                    nRows = Math.Min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
                    nRows = Math.Max(nRows, 1);

                    int[] pixels = new int[width * nRows];
                    Array.Copy(this.pixelData, width * startRow, pixels, 0, width * nRows);

                    /*
                     * Create a data chunk. scanLines adds "nRows" for
                     * the filter bytes.
                     */
                    scanLines = new byte[width * nRows * bytesPerPixel + nRows];

                    if (filter == FILTER_SUB)
                    {
                        leftBytes = new byte[16];
                    }
                    if (filter == FILTER_UP)
                    {
                        priorRow = new byte[width * bytesPerPixel];
                    }

                    scanPos  = 0;
                    startPos = 1;
                    for (int i = 0; i < width * nRows; i++)
                    {
                        if (i % width == 0)
                        {
                            scanLines[scanPos++] = (byte)filter;
                            startPos             = scanPos;
                        }
                        scanLines[scanPos++] = (byte)((pixels[i] >> 16) & 0xff);
                        scanLines[scanPos++] = (byte)((pixels[i] >> 8) & 0xff);
                        scanLines[scanPos++] = (byte)((pixels[i]) & 0xff);
                        if (encodeAlpha)
                        {
                            scanLines[scanPos++] = (byte)((pixels[i] >> 24) & 0xff);
                        }
                        if ((i % width == width - 1) && (filter != FILTER_NONE))
                        {
                            if (filter == FILTER_SUB)
                            {
                                FilterSub(scanLines, startPos, width);
                            }
                            if (filter == FILTER_UP)
                            {
                                FilterUp(scanLines, startPos, width);
                            }
                        }
                    }

                    /*
                     * Write these lines to the output area
                     */
                    compBytes.Write(scanLines, 0, scanPos);

                    startRow += nRows;
                    rowsLeft -= nRows;
                }
                compBytes.Close();

                /*
                 * Write the compressed bytes
                 */
                compressedLines = outBytes.ToArray();
                nCompressed     = compressedLines.Length;

                crc.Reset();
                bytePos = WriteInt4(nCompressed, bytePos);
                bytePos = WriteBytes(IDAT, bytePos);
                crc.Update(IDAT);
                bytePos = WriteBytes(compressedLines, nCompressed, bytePos);
                crc.Update(compressedLines, 0, nCompressed);

                crcValue = crc.Value;
                bytePos  = WriteInt4((int)crcValue, bytePos);
                scrunch.Finish();
                return(true);
            } catch {
                return(false);
            }
        }