enhanced the (already fast!) png exporter

pull/402/head
Michael Peter Christen 4 years ago
parent 4e9b425f98
commit fcc9386ed3

@ -972,6 +972,7 @@ public class RasterPlotter {
/*
* The following code was transformed from a library, coded by J. David Eisenberg, version 1.5, 19 Oct 2003 (C) LGPL
* see: http://catcode.com/pngencoder/index.html
* This code was very strongly transformed into the following very short method for an ultra-fast png generation.
* These changes had been made 23.10.2012 by [MC] to the original code:
* For the integration into YaCy this class was adopted to YaCy graphics by Michael Christen:
@ -986,7 +987,7 @@ public class RasterPlotter {
* - after all enhancements all class objects were removed; result is just one short static method
* - made objects final where possible
* - removed the PixelGrabber call and replaced it with a call to this.frame which is just a byte[]
* - added more speed woodoo like a buffer around the deflater which makes this much faster
* - added more speed voodoo like a buffer around the deflater which makes this much faster
*/
private static final byte IHDR[] = {73, 72, 68, 82};
@ -1000,7 +1001,7 @@ public class RasterPlotter {
final Deflater scrunch = new Deflater(compressionLevel);
ByteBuffer outBytes = new ByteBuffer(1024);
final OutputStream compBytes = new BufferedOutputStream(new DeflaterOutputStream(outBytes, scrunch));
final OutputStream compBytes = new BufferedOutputStream(new DeflaterOutputStream(outBytes, scrunch, 2048, false), 16384);
int i = 0;
for (int row = 0; row < height; row++) {
compBytes.write(0);
@ -1013,42 +1014,46 @@ public class RasterPlotter {
// finally write the result of the concurrent calculation into an DeflaterOutputStream to compress the png
final int nCompressed = outBytes.length();
final byte[] pngBytes = new byte[nCompressed + 57]; // yes thats the exact size, not too less, not too much. No resizing needed.
int bytePos = writeBytes(pngBytes, new byte[]{-119, 80, 78, 71, 13, 10, 26, 10}, 0);
final int startPos = bytePos = writeInt4(pngBytes, 13, bytePos);
bytePos = writeBytes(pngBytes, IHDR, bytePos);
bytePos = writeInt4(pngBytes, width, bytePos);
bytePos = writeInt4(pngBytes, height, bytePos);
bytePos = writeBytes(pngBytes, new byte[]{8, 2, 0, 0, 0}, bytePos);
final byte[] png = new byte[nCompressed + 57]; // yes thats the exact size, not too less, not too much. No resizing needed.
int next = writeBytes(png, new byte[]{-119, 80, 78, 71, 13, 10, 26, 10}, 0);
final int startPos = next = writeInt4(png, 13, next);
next = writeBytes(png, IHDR, next);
next = writeInt4(png, width, next);
next = writeInt4(png, height, next);
next = writeBytes(png, new byte[]{8, 2, 0, 0, 0}, next);
final CRC32 crc = new CRC32();
crc.reset();
crc.update(pngBytes, startPos, bytePos - startPos);
bytePos = writeInt4(pngBytes, (int) crc.getValue(), bytePos);
crc.update(png, startPos, next - startPos);
next = writeInt4(png, (int) crc.getValue(), next);
crc.reset();
bytePos = writeInt4(pngBytes, nCompressed, bytePos);
bytePos = writeBytes(pngBytes, IDAT, bytePos);
next = writeInt4(png, nCompressed, next);
next = writeBytes(png, IDAT, next);
crc.update(IDAT);
outBytes.copyTo(pngBytes, bytePos);
outBytes.copyTo(png, next);
outBytes.close();
outBytes = null;
crc.update(pngBytes, bytePos, nCompressed);
bytePos += nCompressed;
bytePos = writeInt4(pngBytes, (int) crc.getValue(), bytePos);
bytePos = writeInt4(pngBytes, 0, bytePos);
bytePos = writeBytes(pngBytes, IEND, bytePos);
crc.update(png, next, nCompressed);
next += nCompressed;
next = writeInt4(png, (int) crc.getValue(), next);
next = writeInt4(png, 0, next);
next = writeBytes(png, IEND, next);
crc.reset();
crc.update(IEND);
bytePos = writeInt4(pngBytes, (int) crc.getValue(), bytePos);
return pngBytes;
next = writeInt4(png, (int) crc.getValue(), next);
return png;
}
private final static int writeInt4(final byte[] target, final int n, final int offset) {
return writeBytes(target, new byte[]{(byte) ((n >> 24) & 0xff), (byte) ((n >> 16) & 0xff), (byte) ((n >> 8) & 0xff), (byte) (n & 0xff)}, offset);
private final static int writeInt4(final byte[] target, final int n, int pos) {
target[pos++] = (byte) ((n >> 24) & 0xff);
target[pos++] = (byte) ((n >> 16) & 0xff);
target[pos++] = (byte) ((n >> 8) & 0xff);
target[pos++] = (byte) ( n & 0xff);
return pos;
}
private final static int writeBytes(final byte[] target, final byte[] data, final int offset) {
System.arraycopy(data, 0, target, offset, data.length);
return offset + data.length;
private final static int writeBytes(final byte[] target, final byte[] data, final int pos) {
System.arraycopy(data, 0, target, pos, data.length);
return pos + data.length;
}
public static void main(final String[] args) {

Loading…
Cancel
Save