/** * 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; } }
/** * 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); } }