|
|
|
@ -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) {
|
|
|
|
|