diff --git a/build.xml b/build.xml
index 3adaade9a..3d994d016 100644
--- a/build.xml
+++ b/build.xml
@@ -144,6 +144,7 @@
+
diff --git a/htroot/NetworkPicture.java b/htroot/NetworkPicture.java
index 402af270b..7a8fc00ca 100644
--- a/htroot/NetworkPicture.java
+++ b/htroot/NetworkPicture.java
@@ -44,19 +44,17 @@
// Contributions and changes to the program code must be marked as such.
-import java.awt.image.BufferedImage;
-
import de.anomic.http.httpHeader;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
-
+import de.anomic.ymage.ymagePainter;
import de.anomic.plasma.plasmaGrafics;
// draw a picture of the yacy network
public class NetworkPicture {
- public static BufferedImage respond(httpHeader header, serverObjects post, serverSwitch env) {
+ public static ymagePainter respond(httpHeader header, serverObjects post, serverSwitch env) {
int width = 640;
int height = 480;
@@ -77,7 +75,7 @@ public class NetworkPicture {
if (passiveLimit > 500) passiveLimit = 500;
if (potentialLimit > 500) potentialLimit = 500;
if (maxCount > 1000) maxCount = 1000;
- return plasmaGrafics.getNetworkPicture(10000, width, height, passiveLimit, potentialLimit, maxCount).toImage(true);
+ return plasmaGrafics.getNetworkPicture(10000, width, height, passiveLimit, potentialLimit, maxCount);
}
}
diff --git a/htroot/SearchEventPicture.java b/htroot/SearchEventPicture.java
index eafefa947..9cdf0ee66 100644
--- a/htroot/SearchEventPicture.java
+++ b/htroot/SearchEventPicture.java
@@ -51,18 +51,20 @@ import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
import de.anomic.plasma.plasmaGrafics;
-import de.anomic.tools.ImagePainter;
+import de.anomic.ymage.ymagePainter;
+import de.anomic.ymage.ymageMatrixPainter;
+import de.anomic.ymage.ymageMatrix;
// draw a picture of the yacy network
public class SearchEventPicture {
- public static BufferedImage respond(httpHeader header, serverObjects post, serverSwitch env) {
+ public static ymagePainter respond(httpHeader header, serverObjects post, serverSwitch env) {
- ImagePainter ip = plasmaGrafics.getSearchEventPicture();
- if (ip == null) return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); // empty image
+ ymagePainter yp = plasmaGrafics.getSearchEventPicture();
+ if (yp == null) return new ymageMatrixPainter(1, 1, "000000"); // empty image
- return ip.toImage(true);
+ return yp;
}
}
diff --git a/htroot/imagetest.java b/htroot/imagetest.java
index 299c1dbf9..558ca617b 100644
--- a/htroot/imagetest.java
+++ b/htroot/imagetest.java
@@ -46,7 +46,9 @@
import de.anomic.http.httpHeader;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
-import de.anomic.tools.ImagePainter;
+import de.anomic.ymage.ymagePainter;
+import de.anomic.ymage.ymageMatrixPainter;
+import de.anomic.ymage.ymageMatrix;
import java.awt.Graphics2D;
import java.awt.Color;
@@ -64,7 +66,7 @@ import java.lang.reflect.Method;
public class imagetest {
- public static BufferedImage respond(httpHeader header, serverObjects post, serverSwitch env) {
+ public static ymagePainter respond(httpHeader header, serverObjects post, serverSwitch env) {
/*
BufferedImage bi = new BufferedImage(640, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
@@ -96,26 +98,26 @@ public class imagetest {
for (int i = 20; i < 100; i++) r.setPixel(i, 34, new int[]{0, 0, 255});
return bi;
*/
- ImagePainter img = new ImagePainter(800, 600, 0);
+ ymagePainter img = new ymageMatrixPainter(800, 600, "000000");
- img.setMode(ImagePainter.MODE_ADD);
- img.setColor(ImagePainter.ADDITIVE_BLACK);
+ img.setMode(ymageMatrix.MODE_ADD);
+ img.setColor(ymageMatrix.ADDITIVE_BLACK);
for (int y = 0; y < 600; y = y + 50) img.print(0, 6 + y, 0, "" + y, true);
for (int x = 0; x < 800; x = x + 50) img.print(x, 6 , 0, "" + x, true);
- img.setColor(ImagePainter.ADDITIVE_RED);
+ img.setColor(ymageMatrix.ADDITIVE_RED);
img.dot(550, 110, 90, true);
- img.setColor(ImagePainter.ADDITIVE_GREEN);
+ img.setColor(ymageMatrix.ADDITIVE_GREEN);
img.dot(480, 200, 90, true);
- img.setColor(ImagePainter.ADDITIVE_BLUE);
+ img.setColor(ymageMatrix.ADDITIVE_BLUE);
img.dot(620, 200, 90, true);
- img.setColor(ImagePainter.ADDITIVE_RED);
+ img.setColor(ymageMatrix.ADDITIVE_RED);
img.arc(300, 270, 30, 70, 0, 360);
img.setColor("330000");
img.arc(220, 110, 50, 90, 30, 110);
img.arc(210, 120, 50, 90, 30, 110);
- img.setColor(ImagePainter.ADDITIVE_BLACK);
+ img.setColor(ymageMatrix.ADDITIVE_BLACK);
img.print(50, 110, 0, "BROADCAST MESSAGE #772: NODE %882 BLACK abcefghijklmnopqrstuvwxyz", true);
- img.setColor(ImagePainter.ADDITIVE_GREEN);
+ img.setColor(ymageMatrix.ADDITIVE_GREEN);
img.print(50, 120, 0, "BROADCAST MESSAGE #772: NODE %882 GREEN abcefghijklmnopqrstuvwxyz", true);
for (long i = 0; i < 256; i++) {
img.setColor(i);
@@ -138,14 +140,14 @@ public class imagetest {
for (int i = 0; i <= 360; i++) {
img.arc(550, 400, 40, 41 + i/9, 0, i);
}
- img.setColor(ImagePainter.ADDITIVE_BLACK);
+ img.setColor(ymageMatrix.ADDITIVE_BLACK);
int angle;
for (byte c = (byte) 'A'; c <= 'Z'; c++) {
angle = ((byte) c - (byte) 'A') * 360 / ((byte) 'Z' - (byte) 'A');
img.arcLine(550, 400, 81, 100, angle);
img.arcPrint(550, 400, 100, angle, "ANGLE" + angle + ":" + (char) c);
}
- return img.toImage(true);
+ return img;
}
diff --git a/source/dbtest.java b/source/dbtest.java
index b18edcc6d..81ea9efeb 100644
--- a/source/dbtest.java
+++ b/source/dbtest.java
@@ -14,7 +14,8 @@ import java.util.Date;
import de.anomic.server.serverCodings;
import de.anomic.kelondro.kelondroIndex;
import de.anomic.kelondro.kelondroTree;
-import de.anomic.tools.ImageChart;
+import de.anomic.ymage.ymageChart;
+import de.anomic.ymage.ymagePNGEncoderAWT;
import de.anomic.server.serverMemory;
public class dbtest {
@@ -215,7 +216,7 @@ final class dbTable implements kelondroIndex {
final class memprofiler extends Thread {
- ImageChart memChart;
+ ymageChart memChart;
boolean run;
File outputFile;
long start;
@@ -223,11 +224,11 @@ final class memprofiler extends Thread {
public memprofiler(int width, int height, int expectedTimeSeconds, File outputFile) {
this.outputFile = outputFile;
int expectedKilobytes = (int) 20 * 1024;//(Runtime.getRuntime().totalMemory() / 1024);
- memChart = new ImageChart(width, height, "000010", 50, 20, 20, 20, "MEMORY CHART FROM EXECUTION AT " + new Date());
+ memChart = new ymageChart(width, height, "000010", 50, 20, 20, 20, "MEMORY CHART FROM EXECUTION AT " + new Date());
int timescale = 10; // steps with each 10 seconds
int memscale = 1024;
- memChart.declareDimension(ImageChart.DIMENSION_BOTTOM, timescale, (width - 40) * timescale / expectedTimeSeconds, "FFFFFF", "555555", "SECONDS");
- memChart.declareDimension(ImageChart.DIMENSION_LEFT, memscale, (height - 40) * memscale / expectedKilobytes , "FFFFFF", "555555", "KILOBYTES");
+ memChart.declareDimension(ymageChart.DIMENSION_BOTTOM, timescale, (width - 40) * timescale / expectedTimeSeconds, "FFFFFF", "555555", "SECONDS");
+ memChart.declareDimension(ymageChart.DIMENSION_LEFT, memscale, (height - 40) * memscale / expectedKilobytes , "FFFFFF", "555555", "KILOBYTES");
run = true;
start = System.currentTimeMillis();
}
@@ -239,13 +240,13 @@ final class memprofiler extends Thread {
memChart.setColor("FF0000");
seconds1 = (int) ((System.currentTimeMillis() - start) / 1000);
kilobytes1 = (int) (serverMemory.used() / 1024);
- memChart.chartLine(ImageChart.DIMENSION_BOTTOM, ImageChart.DIMENSION_LEFT, seconds0, kilobytes0, seconds1, kilobytes1);
+ memChart.chartLine(ymageChart.DIMENSION_BOTTOM, ymageChart.DIMENSION_LEFT, seconds0, kilobytes0, seconds1, kilobytes1);
seconds0 = seconds1;
kilobytes0 = kilobytes1;
try {Thread.sleep(100);} catch (InterruptedException e) {}
}
try {
- memChart.toPNG(true, outputFile);
+ ymagePNGEncoderAWT.toPNG(memChart, true, outputFile);
} catch (IOException e) {}
}
diff --git a/source/de/anomic/http/httpdFileHandler.java b/source/de/anomic/http/httpdFileHandler.java
index 4eba231f2..d9c3e3679 100644
--- a/source/de/anomic/http/httpdFileHandler.java
+++ b/source/de/anomic/http/httpdFileHandler.java
@@ -96,8 +96,7 @@ import java.util.Properties;
import java.util.logging.Level;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import java.awt.image.BufferedImage;
-import javax.imageio.ImageIO;
+import javax.imageio.ImageIO;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.plasma.plasmaParser;
@@ -110,7 +109,10 @@ import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
import de.anomic.server.logging.serverLog;
import de.anomic.data.userDB;
-
+import de.anomic.ymage.ymagePainter;
+import de.anomic.ymage.ymageMatrixPainter;
+import de.anomic.ymage.ymagePNGEncoderAWT;
+import de.anomic.ymage.ymagePNGEncoderJDE;
public final class httpdFileHandler extends httpdAbstractHandler implements httpdHandler {
@@ -456,12 +458,12 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
if ((targetClass != null) && (path.endsWith("png"))) {
// call an image-servlet to produce an on-the-fly - generated image
- BufferedImage bi = null;
+ ymagePainter yp = null;
try {
requestHeader.put("CLIENTIP", conProp.getProperty("CLIENTIP"));
requestHeader.put("PATH", path);
// in case that there are no args given, args = null or empty hashmap
- bi = (BufferedImage) rewriteMethod(targetClass).invoke(null, new Object[] {requestHeader, args, switchboard});
+ yp = (ymagePainter) rewriteMethod(targetClass).invoke(null, new Object[] {requestHeader, args, switchboard});
} catch (InvocationTargetException e) {
this.theLogger.logSevere("INTERNAL ERROR: " + e.toString() + ":" +
e.getMessage() +
@@ -471,7 +473,7 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
"; java.awt.graphicsenv='" + System.getProperty("java.awt.graphicsenv","") + "'",e);
targetClass = null;
}
- if (bi == null) {
+ if (yp == null) {
// error with image generation; send file-not-found
httpd.sendRespondError(this.connectionProperties,out,3,404,"File not Found",null,null);
} else {
@@ -481,7 +483,9 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
// generate an byte array from the generated image
serverByteBuffer baos = new serverByteBuffer();
- ImageIO.write(bi, targetExt, baos);
+ //ymagePNGEncoderJDE jde = new ymagePNGEncoderJDE((ymageMatrixPainter) yp, ymagePNGEncoderJDE.FILTER_NONE, 0);
+ //byte[] result = jde.pngEncode();
+ ImageIO.write(ymagePNGEncoderAWT.toImage((ymageMatrixPainter) yp, true), targetExt, baos);
byte[] result = baos.toByteArray();
baos.close(); baos = null;
diff --git a/source/de/anomic/plasma/plasmaGrafics.java b/source/de/anomic/plasma/plasmaGrafics.java
index c0b66c442..d2217d63d 100644
--- a/source/de/anomic/plasma/plasmaGrafics.java
+++ b/source/de/anomic/plasma/plasmaGrafics.java
@@ -45,12 +45,13 @@
package de.anomic.plasma;
-import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.util.Enumeration;
import java.util.Date;
-import de.anomic.tools.ImagePainter;
+import de.anomic.ymage.ymagePainter;
+import de.anomic.ymage.ymageMatrix;
+import de.anomic.ymage.ymageMatrixPainter;
import de.anomic.yacy.yacyCore;
import de.anomic.yacy.yacySeed;
@@ -61,17 +62,17 @@ public class plasmaGrafics {
private static int shortestName = 10;
private static int longestName = 12;
- private static ImagePainter networkPicture = null;
+ private static ymagePainter networkPicture = null;
private static long networkPictureDate = 0;
- public static ImagePainter getSearchEventPicture() {
+ public static ymagePainter getSearchEventPicture() {
if (plasmaSearchEvent.lastEvent == null) return null;
yacySearch[] searches = plasmaSearchEvent.lastEvent.getSearchThreads();
if (searches == null) return null; // this was a local search and there are no threads
// get a copy of a recent network picture
- ImagePainter eventPicture = (ImagePainter) getNetworkPicture(120000).clone();
+ ymagePainter eventPicture = (ymagePainter) getNetworkPicture(120000).clone();
// get dimensions
int cr = Math.min(eventPicture.getWidth(), eventPicture.getHeight()) / 5 - 20;
@@ -83,7 +84,7 @@ public class plasmaGrafics {
// draw in the search peers
for (int j = 0; j < searches.length; j++) {
- eventPicture.setColor((searches[j].isAlive()) ? ImagePainter.ADDITIVE_RED : ImagePainter.ADDITIVE_GREEN);
+ eventPicture.setColor((searches[j].isAlive()) ? ymageMatrix.ADDITIVE_RED : ymageMatrix.ADDITIVE_GREEN);
hash = searches[j].target().hash;
angle = (int) ((long) 360 * (yacySeed.dhtPosition(hash) / (yacySeed.maxDHTDistance / (long) 10000)) / (long) 10000);
eventPicture.arcLine(cx, cy, cr - 20, cr, angle);
@@ -92,8 +93,8 @@ public class plasmaGrafics {
// draw in the search target
plasmaSearchQuery query = plasmaSearchEvent.lastEvent.getQuery();
Iterator i = query.queryHashes.iterator();
- eventPicture.setMode(ImagePainter.MODE_ADD);
- eventPicture.setColor(ImagePainter.ADDITIVE_BLACK);
+ eventPicture.setMode(ymageMatrix.MODE_ADD);
+ eventPicture.setColor(ymageMatrix.ADDITIVE_BLACK);
while (i.hasNext()) {
hash = (String) i.next();
angle = (int) ((long) 360 * (yacySeed.dhtPosition(hash) / (yacySeed.maxDHTDistance / (long) 10000)) / (long) 10000);
@@ -103,11 +104,11 @@ public class plasmaGrafics {
return eventPicture;
}
- public static ImagePainter getNetworkPicture(long maxAge) {
+ public static ymagePainter getNetworkPicture(long maxAge) {
return getNetworkPicture(maxAge, 640, 480, 300, 300, 1000);
}
- public static ImagePainter getNetworkPicture(long maxAge, int width, int height, int passiveLimit, int potentialLimit, int maxCount) {
+ public static ymagePainter getNetworkPicture(long maxAge, int width, int height, int passiveLimit, int potentialLimit, int maxCount) {
if ((networkPicture == null) || ((System.currentTimeMillis() - networkPictureDate) > maxAge)) {
drawNetworkPicture(width, height, passiveLimit, potentialLimit, maxCount);
}
@@ -122,8 +123,8 @@ public class plasmaGrafics {
if (yacyCore.seedDB == null) return; // no other peers known
- networkPicture = new ImagePainter(width, height, "000010");
- networkPicture.setMode(ImagePainter.MODE_ADD);
+ networkPicture = new ymageMatrixPainter(width, height, "000010");
+ networkPicture.setMode(ymageMatrix.MODE_ADD);
// draw network circle
networkPicture.setColor("008020");
@@ -182,7 +183,7 @@ public class plasmaGrafics {
// draw description
networkPicture.setColor("FFFFFF");
- networkPicture.setMode(ImagePainter.MODE_ADD);
+ networkPicture.setMode(ymageMatrix.MODE_ADD);
networkPicture.print(2, 8, 0, "THE YACY NETWORK", true);
networkPicture.print(2, 16, 0, "DRAWING OF " + totalCount + " SELECTED PEERS", true);
networkPicture.print(width - 2, 8, 0, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), false);
@@ -191,7 +192,7 @@ public class plasmaGrafics {
networkPictureDate = System.currentTimeMillis();
}
- private static void drawNetworkPicturePeer(ImagePainter img, int x, int y, int innerradius, int outerradius, yacySeed seed, String colorDot, String colorLine, String colorText) {
+ private static void drawNetworkPicturePeer(ymagePainter img, int x, int y, int innerradius, int outerradius, yacySeed seed, String colorDot, String colorLine, String colorText) {
String name = seed.getName().toUpperCase();
if (name.length() < shortestName) shortestName = name.length();
if (name.length() > longestName) longestName = name.length();
@@ -201,7 +202,7 @@ public class plasmaGrafics {
if (linelength > outerradius) linelength = outerradius;
int dotsize = 6 + 2 * (int) (seed.getLinkCount() / 500000L);
if (dotsize > 18) dotsize = 18;
- img.setMode(ImagePainter.MODE_ADD);
+ img.setMode(ymageMatrix.MODE_ADD);
// draw dot
img.setColor(colorDot);
img.arcDot(x, y, innerradius, angle, dotsize);
@@ -217,7 +218,7 @@ public class plasmaGrafics {
if (ppm10 > 3) ppm10 = 3;
// draw a wave around crawling peers
long strength;
- img.setMode(ImagePainter.MODE_SUB);
+ img.setMode(ymageMatrix.MODE_SUB);
img.setColor("303030");
img.arcArc(x, y, innerradius, angle, dotsize + 1, dotsize + 1, 0, 360);
int waveradius = innerradius / 2;
diff --git a/source/de/anomic/plasma/plasmaURL.java b/source/de/anomic/plasma/plasmaURL.java
index 44b06512b..3c43b9dbd 100644
--- a/source/de/anomic/plasma/plasmaURL.java
+++ b/source/de/anomic/plasma/plasmaURL.java
@@ -143,5 +143,21 @@ public class plasmaURL {
public Iterator urlHashes(String urlHash, boolean up) throws IOException {
return urlHashCache.rows(up, false, urlHash.getBytes());
}
-
+
+ /* TLDs:
+ AC, AD, AE, AERO, AF, AG, AI, AL, AM, AN, AO, AQ, AR, ARPA, AS, AT, AU, AW, AZ,
+ BA, BB, BD, BE, BF, BG, BH, BI, BIZ, BJ, BM, BN, BO, BR, BS, BT, BV, BW, BY, BZ,
+ CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, COM, COOP, CR, CU, CV, CX, CY, CZ,
+ DE, DJ, DK, DM, DO, DZ, EC, EDU, EE, EG, ER, ES, ET, EU, FI, FJ, FK, FM, FO, FR,
+ GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GOV, GP, GQ, GR, GS, GT, GU, GW, GY,
+ HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, INFO, INT, IO, IQ, IR, IS, IT,
+ JE, JM, JO, JOBS, JP, KE, KG, KH, KI, KM, KN, KR, KW, KY, KZ,
+ LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY,
+ MA, MC, MD, MG, MH, MIL, MK, ML, MM, MN, MO, MOBI, MP, MQ, MR, MS, MT, MU, MUSEUM, MV, MW, MX, MY, MZ,
+ NA, NAME, NC, NE, NET, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, ORG,
+ PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PRO, PS, PT, PW, PY, QA, RE, RO, RU, RW,
+ SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, ST, SU, SV, SY, SZ,
+ TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TP, TR, TRAVEL, TT, TV, TW, TZ,
+ UA, UG, UK, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, YE, YT, YU, ZA, ZM, ZW
+ */
}
diff --git a/source/de/anomic/yacy/yacySeed.java b/source/de/anomic/yacy/yacySeed.java
index b48f47b7b..7ce7ae3ed 100644
--- a/source/de/anomic/yacy/yacySeed.java
+++ b/source/de/anomic/yacy/yacySeed.java
@@ -263,7 +263,12 @@ public class yacySeed {
public long getUTCDiff() {
String utc = (String) this.dna.get(UTC);
if (utc == null) { utc = "+0200"; }
- return serverDate.UTCDiff(utc);
+ try {
+ return serverDate.UTCDiff(utc);
+ } catch (RuntimeException e) {
+
+ return 0;
+ }
}
public long getLastSeenTime() {
diff --git a/source/de/anomic/tools/ImageChart.java b/source/de/anomic/ymage/ymageChart.java
similarity index 96%
rename from source/de/anomic/tools/ImageChart.java
rename to source/de/anomic/ymage/ymageChart.java
index 8b278976a..018222978 100644
--- a/source/de/anomic/tools/ImageChart.java
+++ b/source/de/anomic/ymage/ymageChart.java
@@ -1,4 +1,4 @@
-// ImageChart.java
+// ymageChart.java
// ---------------------------
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
@@ -39,12 +39,12 @@
// Contributions and changes to the program code must be marked as such.
-package de.anomic.tools;
+package de.anomic.ymage;
import java.io.File;
import java.io.IOException;
-public class ImageChart extends ImagePainter {
+public class ymageChart extends ymageMatrixPainter {
public static final int DIMENSION_RIGHT = 0;
public static final int DIMENSION_TOP = 1;
@@ -61,7 +61,7 @@ public class ImageChart extends ImagePainter {
String[] colscale = new String[]{null,null,null,null};
String[] tablenames = new String[]{"","","",""};
- public ImageChart(int width, int height, String backgroundColor,
+ public ymageChart(int width, int height, String backgroundColor,
int leftborder, int rightborder, int topborder, int bottomborder,
String name) {
super(width, height, backgroundColor);
@@ -149,7 +149,7 @@ public class ImageChart extends ImagePainter {
public static void main(String[] args) {
System.setProperty("java.awt.headless", "true");
- ImageChart ip = new ImageChart(640, 480, "000010", 40, 40, 20, 20, "TESTCHART");
+ ymageChart ip = new ymageChart(640, 480, "000010", 40, 40, 20, 20, "TESTCHART");
ip.declareDimension(DIMENSION_BOTTOM, 10, 30, "FFFFFF", "555555", "time");
ip.declareDimension(DIMENSION_TOP, 10, 40, "FFFFFF", null, "count");
ip.declareDimension(DIMENSION_LEFT, 100, 30, "FFFFFF", "555555", "money");
@@ -161,9 +161,11 @@ public class ImageChart extends ImagePainter {
//ip.print(100, 100, 0, "1234", false);
//ip.print(100, 100, 90, "TEXT", true);
//ip.print(100, 100, 90, "1234", false);
+ /*
try {
ip.toPNG(true, new File("/Users/admin/dev/yacy/trunk/testimage.png"));
} catch (IOException e) {}
+ */
}
}
diff --git a/source/de/anomic/ymage/ymageFontGenerator.java b/source/de/anomic/ymage/ymageFontGenerator.java
new file mode 100644
index 000000000..189147c8b
--- /dev/null
+++ b/source/de/anomic/ymage/ymageFontGenerator.java
@@ -0,0 +1,573 @@
+// ymageFontGenerator.java
+// ---------------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2005
+// created: 31.10.2005
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+package de.anomic.ymage;
+
+public class ymageFontGenerator {
+
+/*
+?0x20: !"#$%&'
+0x28:()*+,-./
+0x30:01234567
+0x38:89:;<=>?
+0x40:@ABCDEFG
+0x48:HIJKLMNO
+0x50:PQRSTUVW
+0x58:XYZ[\]^_
+0x60:`abcdefg
+0x68:hijklmno
+0x70:pqrstuvw
+0x78:xyz{|}~
+*/
+
+ public static final String[][] font =
+ {
+ {".....", //0x20
+ ".....",
+ ".....",
+ ".....",
+ "....."},
+ {"..X..",
+ "..X..",
+ "..X..",
+ ".....",
+ "..X.."},
+ {".X.X.",
+ ".X.X.",
+ ".....",
+ ".....",
+ "....."},
+ {".X.X.",
+ "XXXXX",
+ ".X.X.",
+ "XXXXX",
+ ".X.X."},
+ {".XXXX",
+ "X.X..",
+ ".XXX.",
+ "..X.X",
+ "XXXX."},
+ {".X..X",
+ "X.XX.",
+ ".XXX.",
+ ".XX.X",
+ "X..X."},
+ {".XXX.",
+ "X....",
+ ".X.X.",
+ "X.X..",
+ ".X.X."},
+ {"..X..",
+ "..X..",
+ ".....",
+ ".....",
+ "....."},
+ {"...X.", //0x28
+ "..X..",
+ "..X..",
+ "..X..",
+ "...X."},
+ {".X...",
+ "..X..",
+ "..X..",
+ "..X..",
+ ".x..."},
+ {".....",
+ ".X.X.",
+ "xxXxx",
+ ".x.X.",
+ "....."},
+ {".....",
+ "..X..",
+ ".XXX.",
+ "..X..",
+ "....."},
+ {".....",
+ ".....",
+ "..X..",
+ "..X..",
+ ".X..."},
+ {".....",
+ ".....",
+ ".XXX.",
+ ".....",
+ "....."},
+ {".....",
+ ".....",
+ ".....",
+ ".....",
+ "..X.."},
+ {"....X",
+ "...X.",
+ "..X..",
+ ".X...",
+ "X...."},
+ {".XXX.", //0x30
+ "X..XX",
+ "X.X.X",
+ "XX..X",
+ ".XXX."},
+ {"..X..",
+ ".XX..",
+ "..X..",
+ "..X..",
+ ".XXX."},
+ {".XXX.",
+ "X...X",
+ "..XX.",
+ ".X...",
+ "XXXXX"},
+ {".XXX.",
+ "X...X",
+ "...X.",
+ "X...X",
+ ".XXX."},
+ {"..XX.",
+ ".X.X.",
+ "XXXXX",
+ "...X.",
+ "...X."},
+ {"XXXXX",
+ "X....",
+ "XXXX.",
+ "....X",
+ "XXXX."},
+ {".XXX.",
+ "X....",
+ "XXXX.",
+ "X...X",
+ ".XXX."},
+ {"XXXXX",
+ "...X.",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {".XXX.", //0x38
+ "X...X",
+ ".XXX.",
+ "X...X",
+ ".XXX."},
+ {".XXX.",
+ "X...X",
+ ".XXXX",
+ "....X",
+ ".XXX."},
+ {".....",
+ "..X..",
+ ".....",
+ "..X..",
+ "....."},
+ {".....",
+ "..X..",
+ ".....",
+ "..X..",
+ ".X..."},
+ {"...X.",
+ "..X..",
+ ".X...",
+ "..X..",
+ "...X."},
+ {".....",
+ "XXXXX",
+ ".....",
+ "XXXXX",
+ "....."},
+ {".X...",
+ "..X..",
+ "...X.",
+ "..X..",
+ ".X..."},
+ {".XXX.",
+ "...X.",
+ "..X..",
+ ".....",
+ "..X.."},
+ {".XXX.", //0x40
+ "XXX.X",
+ "XXXX.",
+ "X....",
+ ".XXX."},
+ {"..X..",
+ ".X.X.",
+ "X...X",
+ "XXXXX",
+ "X...X"},
+ {"XXX..",
+ "X..X.",
+ "XXXX.",
+ "X...X",
+ "XXXX."},
+ {".XXX.",
+ "X....",
+ "X....",
+ "X....",
+ ".XXX."},
+ {"XXXX.",
+ "X...X",
+ "X...X",
+ "X...X",
+ "XXXX."},
+ {"XXXXX",
+ "X....",
+ "XXX..",
+ "X....",
+ "XXXXX"},
+ {"XXXXX",
+ "X....",
+ "XXX..",
+ "X....",
+ "X...."},
+ {".XXX.",
+ "X....",
+ "X.XXX",
+ "X...X",
+ ".XXX."},
+ {"X...X", //0x48
+ "X...X",
+ "XXXXX",
+ "X...X",
+ "X...X"},
+ {"XXXXX",
+ "..X..",
+ "..X..",
+ "..X..",
+ "XXXXX"},
+ {"XXXXX",
+ "....X",
+ "....X",
+ "X...X",
+ ".XXX."},
+ {"X...X",
+ "X..X.",
+ "XXX..",
+ "X..X..",
+ "X...X"},
+ {"X....",
+ "X....",
+ "X....",
+ "X....",
+ "XXXXX"},
+ {"X...X",
+ "XX.XX",
+ "X.X.X",
+ "X...X",
+ "X...X"},
+ {"X...X",
+ "XX..X",
+ "X.X.X",
+ "X..XX",
+ "X...X"},
+ {".XXX.",
+ "X...X",
+ "X...X",
+ "X...X",
+ ".XXX."},
+ {"XXXX.", //0x50
+ "X...X",
+ "XXXX.",
+ "X....",
+ "X...."},
+ {".XXX.",
+ "X...X",
+ "X.X.X",
+ "X..X.",
+ ".XX.X"},
+ {"XXXX.",
+ "X...X",
+ "XXXX.",
+ "X..X.",
+ "X...X"},
+ {".XXX.",
+ "X....",
+ ".XXX.",
+ "....X",
+ ".XXX."},
+ {"XXXXX",
+ "..X..",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {"X...X",
+ "X...X",
+ "X...X",
+ "X...X",
+ ".XXX."},
+ {"X...X",
+ "X...X",
+ "X...X",
+ ".X.X.",
+ "..X.."},
+ {"X...X",
+ "X...X",
+ "X...X",
+ "X.X.X",
+ ".X.X."},
+ {"X...X", //0x58
+ ".X.X.",
+ "..X..",
+ ".X.X.",
+ "X...X"},
+ {"X...X",
+ ".X.X.",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {"XXXXX",
+ "...X.",
+ "..X..",
+ ".X...",
+ "XXXXX"},
+ {".XXX.",
+ ".X...",
+ ".X...",
+ ".X...",
+ ".XXX."},
+ {"X....",
+ ".X...",
+ "..X..",
+ "...X.",
+ "....X"},
+ {".XXX.",
+ "...X.",
+ "...X.",
+ "...X.",
+ ".XXX."},
+ {"..X..",
+ ".X.X.",
+ "X...X",
+ ".....",
+ "....."},
+ {".....",
+ ".....",
+ ".....",
+ ".....",
+ "XXXXX"},
+ {".X...", //0x60
+ "..X..",
+ ".....",
+ ".....",
+ "....."},
+ {".....",
+ ".....",
+ ".XXXX",
+ "X...X",
+ ".XXXX"},
+ {"X....",
+ "X....",
+ "XXXX.",
+ "X...X",
+ "XXXX."},
+ {".....",
+ ".....",
+ ".XXXX",
+ "X....",
+ ".XXXX"},
+ {"....X",
+ "....X",
+ ".XXXX",
+ "X...X",
+ ".XXXX"},
+ {".....",
+ ".XX..",
+ "X..X.",
+ "X.X..",
+ ".XXXX"},
+ {"..XX.",
+ "..X..",
+ ".XXX.",
+ "..X..",
+ "..X.."},
+ {".....",
+ "..XX.",
+ ".X..X",
+ "..X.X",
+ "XXXX."},
+ {"X....", //0x68
+ "X....",
+ "X.XX.",
+ "XX..X",
+ "X...X"},
+ {"..X..",
+ ".....",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {"..X..",
+ ".....",
+ "..X..",
+ "..X..",
+ ".X..."},
+ {"X....",
+ "X....",
+ "X..XX",
+ "XXX..",
+ "X..XX"},
+ {"..X..",
+ "..X..",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {".....",
+ ".....",
+ ".X.X.",
+ "X.X.X",
+ "X.X.X"},
+ {".....",
+ ".....",
+ ".XXX.",
+ "X...X",
+ "X...X"},
+ {".....",
+ ".....",
+ ".XXX.",
+ "X...X",
+ ".XXX."},
+ {".....", //0x70
+ "XXXX.",
+ "X...X",
+ "XXXX.",
+ "X...."},
+ {".....",
+ ".XXXX",
+ "X...X",
+ ".XXXX",
+ "....X"},
+ {".....",
+ "...X.",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {".....",
+ ".....",
+ "..XX.",
+ ".X..X",
+ "X..X."},
+ {"..X..",
+ ".XXX.",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {".....",
+ ".....",
+ "X...X",
+ "X...X",
+ ".XXX."},
+ {".....",
+ ".....",
+ "X...X",
+ ".X.X.",
+ "..X.."},
+ {".....",
+ ".....",
+ "X.X.X",
+ "X.X.X",
+ ".X.X."},
+ {".....", //0x78
+ ".....",
+ ".X.X.",
+ "..X..",
+ ".X.X."},
+ {".....",
+ ".....",
+ ".X.X.",
+ "..X..",
+ "..X.."},
+ {".....",
+ ".....",
+ ".XXXX",
+ "..X..",
+ "XXXX."},
+ {"..XX.",
+ "..X..",
+ ".X...",
+ "..X..",
+ "..XX."},
+ {"..X..",
+ "..X..",
+ "..X..",
+ "..X..",
+ "..X.."},
+ {".XX..",
+ "..X..",
+ "...X.",
+ "..X..",
+ ".XX.."},
+ {".....",
+ ".X...",
+ "X.X.X",
+ "...X.",
+ "....."},
+ {"XXXXX",
+ "X...X",
+ "X...X",
+ "X...X",
+ "XXXXX"},
+ };
+
+
+ public static void main(String[] args) {
+ String[] letter;
+ int b;
+ int v;
+ int c = 0;
+ String s;
+ for (int i = 0; i < font.length; i++) {
+ letter = font[i];
+ b = 0;
+ for (int j = 0; j < 5; j++) {
+ b = b << 5;
+ v = 16;
+ for (int col = 0; col < 5; col++) {
+ if (letter[j].charAt(col) == 'X') b += v;
+ v = v >> 1;
+ }
+ }
+ s = Long.toHexString(b).toUpperCase();
+ while (s.length() < 7) s = "0" + s;
+ System.out.print("0x" + s + ",");
+ c++;
+ if (c >= 8) {
+ System.out.println();
+ c = 0;
+ }
+ }
+ }
+
+}
diff --git a/source/de/anomic/ymage/ymageMatrix.java b/source/de/anomic/ymage/ymageMatrix.java
new file mode 100644
index 000000000..55c5f68a5
--- /dev/null
+++ b/source/de/anomic/ymage/ymageMatrix.java
@@ -0,0 +1,228 @@
+// ymageMatrix.java
+// ---------------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2005
+// last major change: 16.09.2005
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+/*
+ This Class implements some convenience-methods to support drawing of statistical Data
+ It is not intended to replace existing awt-funktions even if it looks so
+ This class provides some drawing methods that creates transparency effects that
+ are not available in awt.
+ */
+
+package de.anomic.ymage;
+
+public class ymageMatrix implements Cloneable {
+
+ // colors regarding RGB Color Model
+ public static final long ADDITIVE_RED = 0xFF0000;
+ public static final long ADDITIVE_GREEN = 0x00FF00;
+ public static final long ADDITIVE_BLUE = 0x0000FF;
+ public static final long ADDITIVE_BLACK = 0xFFFFFF;
+
+ // colors regarding CMY Color Model
+ public static final long SUBTRACTIVE_CYAN = 0xFF0000;
+ public static final long SUBTRACTIVE_MAGENTA = 0x00FF00;
+ public static final long SUBTRACTIVE_YELLOW = 0x0000FF;
+ public static final long SUBTRACTIVE_WHITE = 0xFFFFFF;
+
+ public static final byte MODE_REPLACE = 0;
+ public static final byte MODE_ADD = 1;
+ public static final byte MODE_SUB = 2;
+
+
+ protected int width, height;
+ private byte[] grid; // one-dimensional arrays are much faster than two-dimensional
+ private int defaultColR, defaultColG, defaultColB;
+ private byte defaultMode;
+ private boolean grabComplementary = false;
+
+ public ymageMatrix(int width, int height, String backgroundColor) {
+ this(width, height, colNum(backgroundColor));
+ }
+
+ public ymageMatrix(int width, int height, long backgroundColor) {
+ this.width = width;
+ this.height = height;
+ this.defaultColR = 0xFF;
+ this.defaultColG = 0xFF;
+ this.defaultColB = 0xFF;
+ this.defaultMode = MODE_REPLACE;
+ grid = new byte[3*width*height];
+
+ // fill grid with background color
+ byte bgR = (byte) (backgroundColor >> 16);
+ byte bgG = (byte) ((backgroundColor >> 8) & 0xff);
+ byte bgB = (byte) (backgroundColor & 0xff);
+ for (int n = 3 * width * height - 3; n >= 0; n = n - 3) {
+ grid[n ] = bgR;
+ grid[n + 1] = bgG;
+ grid[n + 2] = bgB;
+ }
+ }
+
+ private static long colNum(String col) {
+ return Long.parseLong(col, 16);
+ //return Integer.parseInt(col.substring(0,2), 16) << 16 | Integer.parseInt(col.substring(2,4), 16) << 8 | Integer.parseInt(col.substring(4,6), 16);
+ }
+
+ private static String colStr(long c) {
+ String s = Long.toHexString(c);
+ while (s.length() < 6) s = "0" + s;
+ return s;
+ }
+
+ public Object clone() {
+ ymageMatrix ip = new ymageMatrix(this.width, this.height, 0);
+ System.arraycopy(this.grid, 0, ip.grid, 0, this.grid.length);
+ ip.defaultColR = this.defaultColR;
+ ip.defaultColG = this.defaultColG;
+ ip.defaultColB = this.defaultColB;
+ ip.defaultMode = this.defaultMode;
+ return ip;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setColor(long c) {
+ defaultColR = (int) (c >> 16);
+ defaultColG = (int) ((c >> 8) & 0xff);
+ defaultColB = (int) (c & 0xff);
+ }
+
+ public void setColor(String s) {
+ setColor(colNum(s));
+ }
+
+ public void setMode(byte m) {
+ this.defaultMode = m;
+ }
+
+ public void plot(int x, int y) {
+ if ((x < 0) || (x >= width)) return;
+ if ((y < 0) || (y >= height)) return;
+ int n = 3 * (x + y * width);
+ if (this.defaultMode == MODE_REPLACE) {
+ grid[n ] = (byte) defaultColR;
+ grid[n + 1] = (byte) defaultColG;
+ grid[n + 2] = (byte) defaultColB;
+ } else if (this.defaultMode == MODE_ADD) {
+ int r = ((int) (0xff & grid[n ])) + defaultColR; if (r > 0xff) r = 0xff;
+ int g = ((int) (0xff & grid[n + 1])) + defaultColG; if (g > 0xff) g = 0xff;
+ int b = ((int) (0xff & grid[n + 2])) + defaultColB; if (b > 0xff) b = 0xff;
+ grid[n ] = (byte) r;
+ grid[n + 1] = (byte) g;
+ grid[n + 2] = (byte) b;
+ } else if (this.defaultMode == MODE_SUB) {
+ int r = ((int) (0xff & grid[n ])) - defaultColR; if (r < 0) r = 0;
+ int g = ((int) (0xff & grid[n + 1])) - defaultColG; if (g < 0) g = 0;
+ int b = ((int) (0xff & grid[n + 2])) - defaultColB; if (b < 0) b = 0;
+ grid[n ] = (byte) r;
+ grid[n + 1] = (byte) g;
+ grid[n + 2] = (byte) b;
+ }
+ }
+
+
+ public void line(int Ax, int Ay, int Bx, int By) {
+ // Bresenham's line drawing algorithm
+ int dX = Math.abs(Bx-Ax);
+ int dY = Math.abs(By-Ay);
+ int Xincr, Yincr;
+ if (Ax > Bx) Xincr=-1; else Xincr=1;
+ if (Ay > By) Yincr=-1; else Yincr=1;
+ if (dX >= dY) {
+ int dPr = dY<<1;
+ int dPru = dPr - (dX<<1);
+ int P = dPr - dX;
+ for (; dX>=0; dX--) {
+ plot(Ax, Ay);
+ if (P > 0) {
+ Ax+=Xincr;
+ Ay+=Yincr;
+ P+=dPru;
+ } else {
+ Ax+=Xincr;
+ P+=dPr;
+ }
+ }
+ } else {
+ int dPr = dX<<1;
+ int dPru = dPr - (dY<<1);
+ int P = dPr - dY;
+ for (; dY>=0; dY--) {
+ plot(Ax, Ay);
+ if (P > 0) {
+ Ax+=Xincr;
+ Ay+=Yincr;
+ P+=dPru;
+ } else {
+ Ay+=Yincr;
+ P+=dPr;
+ }
+ }
+ }
+ }
+
+ public void getColorMode(boolean grabComplementary) {
+ this.grabComplementary = grabComplementary;
+ }
+
+ public int[] getColor(int x, int y) {
+ int n = 3 * (x + y * width);
+ if (grabComplementary) {
+ int r = 0xff & grid[n ];
+ int g = 0xff & grid[n + 1];
+ int b = 0xff & grid[n + 2];
+ return new int[]{(0x1fe - g - b) / 2, (0x1fe - r - b) / 2, (0x1fe - r - g) / 2};
+ } else {
+ int r = 0xff & grid[n ];
+ int g = 0xff & grid[n + 1];
+ int b = 0xff & grid[n + 2];
+ return new int[]{r, g, b};
+ }
+ }
+
+
+}
diff --git a/source/de/anomic/tools/ImagePainter.java b/source/de/anomic/ymage/ymageMatrixPainter.java
similarity index 52%
rename from source/de/anomic/tools/ImagePainter.java
rename to source/de/anomic/ymage/ymageMatrixPainter.java
index 17e27480e..6fd8b4fd7 100644
--- a/source/de/anomic/tools/ImagePainter.java
+++ b/source/de/anomic/ymage/ymageMatrixPainter.java
@@ -1,494 +1,258 @@
-// ImagePainter.java
-// ---------------------------
-// (C) by Michael Peter Christen; mc@anomic.de
-// first published on http://www.anomic.de
-// Frankfurt, Germany, 2005
-// last major change: 16.09.2005
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Using this software in any meaning (reading, learning, copying, compiling,
-// running) means that you agree that the Author(s) is (are) not responsible
-// for cost, loss of data or any harm that may be caused directly or indirectly
-// by usage of this softare or this documentation. The usage of this software
-// is on your own risk. The installation and usage (starting/running) of this
-// software may allow other people or application to access your computer and
-// any attached devices and is highly dependent on the configuration of the
-// software which must be done by the user of the software; the author(s) is
-// (are) also not responsible for proper configuration and usage of the
-// software, even if provoked by documentation provided together with
-// the software.
-//
-// Any changes to this file according to the GPL as documented in the file
-// gpl.txt aside this file in the shipment you received can be done to the
-// lines that follows this copyright notice here, but changes must not be
-// done inside the copyright notive above. A re-distribution must contain
-// the intact and unchanged copyright notice.
-// Contributions and changes to the program code must be marked as such.
-
-/*
- This Class implements some convenience-methods to support drawing of statistical Data
- It is not intended to replace existing awt-funktions even if it looks so
- This class provides some drawing methods that creates transparency effects that
- are not available in awt.
- */
-
-package de.anomic.tools;
-
-import java.io.File;
-import java.awt.Graphics2D;
-import java.awt.GraphicsEnvironment;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsConfiguration;
-import java.awt.Transparency;
-import java.awt.Color;
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-import java.util.HashSet;
-import java.util.ArrayList;
-import javax.imageio.ImageIO;
-import java.io.IOException;
-
-public class ImagePainter implements Cloneable {
-
- // colors regarding RGB Color Model
- public static final long ADDITIVE_RED = 0xFF0000;
- public static final long ADDITIVE_GREEN = 0x00FF00;
- public static final long ADDITIVE_BLUE = 0x0000FF;
- public static final long ADDITIVE_BLACK = 0xFFFFFF;
-
- // colors regarding CMY Color Model
- public static final long SUBTRACTIVE_CYAN = 0xFF0000;
- public static final long SUBTRACTIVE_MAGENTA = 0x00FF00;
- public static final long SUBTRACTIVE_YELLOW = 0x0000FF;
- public static final long SUBTRACTIVE_WHITE = 0xFFFFFF;
-
- public static final byte MODE_REPLACE = 0;
- public static final byte MODE_ADD = 1;
- public static final byte MODE_SUB = 2;
-
- private static long[] font = new long[]{
- 0x0000000,0x0421004,0x0A50000,0x0AFABEA,0x0FA38BE,0x09B39B2,0x0E82A8A,0x0420000,
- 0x0221082,0x0821080,0x0051040,0x0023880,0x0001088,0x0003800,0x0000004,0x0111110,
- 0x0E9D72E,0x046108E,0x0E8991F,0x0E88A2E,0x0657C42,0x1F8783E,0x0E87A2E,0x1F11084,
- 0x0E8BA2E,0x0E8BC2E,0x0020080,0x0020088,0x0222082,0x00F83E0,0x0820888,0x0E11004,
- 0x0EEFA0E,0x04547F1,0x1C97A3E,0x0E8420E,0x1E8C63E,0x1F8721F,0x1F87210,0x0E85E2E,
- 0x118FE31,0x1F2109F,0x1F0862E,0x1197251,0x108421F,0x11DD631,0x11CD671,0x0E8C62E,
- 0x1E8FA10,0x0E8D64D,0x1E8FA51,0x0E8382E,0x1F21084,0x118C62E,0x118C544,0x118C6AA,
- 0x1151151,0x1151084,0x1F1111F,0x0E4210E,0x1041041,0x0E1084E,0x0454400,0x000001F,
- 0x0820000,0x0003E2F,0x1087A3E,0x0003E0F,0x010BE2F,0x0064A8F,0x0623884,0x00324BE,
- 0x1085B31,0x0401084,0x0401088,0x1084F93,0x0421084,0x0002AB5,0x0003A31,0x0003A2E,
- 0x00F47D0,0x007C5E1,0x0011084,0x0001932,0x0471084,0x000462E,0x0004544,0x00056AA,
- 0x000288A,0x0002884,0x0003C9E,0x0622086,0x0421084,0x0C2088C,0x0045440,0x1F8C63F
- };
-
- private static int[][] circles = new int[0][];
-
- protected int width, height;
- private byte[] grid; // one-dimensional arrays are much faster than two-dimensional
- private int defaultColR, defaultColG, defaultColB;
- private byte defaultMode;
-
- public ImagePainter(int width, int height, String backgroundColor) {
- this(width, height, colNum(backgroundColor));
- }
-
- public ImagePainter(int width, int height, long backgroundColor) {
- this.width = width;
- this.height = height;
- this.defaultColR = 0xFF;
- this.defaultColG = 0xFF;
- this.defaultColB = 0xFF;
- this.defaultMode = MODE_REPLACE;
- grid = new byte[3*width*height];
-
- // fill grid with background color
- byte bgR = (byte) (backgroundColor >> 16);
- byte bgG = (byte) ((backgroundColor >> 8) & 0xff);
- byte bgB = (byte) (backgroundColor & 0xff);
- for (int n = 3 * width * height - 3; n >= 0; n = n - 3) {
- grid[n ] = bgR;
- grid[n + 1] = bgG;
- grid[n + 2] = bgB;
- }
- }
-
- private static long colNum(String col) {
- return Long.parseLong(col, 16);
- //return Integer.parseInt(col.substring(0,2), 16) << 16 | Integer.parseInt(col.substring(2,4), 16) << 8 | Integer.parseInt(col.substring(4,6), 16);
- }
-
- private static String colStr(long c) {
- String s = Long.toHexString(c);
- while (s.length() < 6) s = "0" + s;
- return s;
- }
-
- public Object clone() {
- ImagePainter ip = new ImagePainter(this.width, this.height, 0);
- System.arraycopy(this.grid, 0, ip.grid, 0, this.grid.length);
- ip.defaultColR = this.defaultColR;
- ip.defaultColG = this.defaultColG;
- ip.defaultColB = this.defaultColB;
- ip.defaultMode = this.defaultMode;
- return ip;
- }
-
- public int getWidth() {
- return width;
- }
-
- public int getHeight() {
- return height;
- }
-
- public void setColor(long c) {
- defaultColR = (int) (c >> 16);
- defaultColG = (int) ((c >> 8) & 0xff);
- defaultColB = (int) (c & 0xff);
- }
-
- public void setColor(String s) {
- setColor(colNum(s));
- }
-
- public void setMode(byte m) {
- this.defaultMode = m;
- }
-
- protected void plot(int x, int y) {
- if ((x < 0) || (x >= width)) return;
- if ((y < 0) || (y >= height)) return;
- int n = 3 * (x + y * width);
- if (this.defaultMode == MODE_REPLACE) {
- grid[n ] = (byte) defaultColR;
- grid[n + 1] = (byte) defaultColG;
- grid[n + 2] = (byte) defaultColB;
- } else if (this.defaultMode == MODE_ADD) {
- int r = ((int) (0xff & grid[n ])) + defaultColR; if (r > 0xff) r = 0xff;
- int g = ((int) (0xff & grid[n + 1])) + defaultColG; if (g > 0xff) g = 0xff;
- int b = ((int) (0xff & grid[n + 2])) + defaultColB; if (b > 0xff) b = 0xff;
- grid[n ] = (byte) r;
- grid[n + 1] = (byte) g;
- grid[n + 2] = (byte) b;
- } else if (this.defaultMode == MODE_SUB) {
- int r = ((int) (0xff & grid[n ])) - defaultColR; if (r < 0) r = 0;
- int g = ((int) (0xff & grid[n + 1])) - defaultColG; if (g < 0) g = 0;
- int b = ((int) (0xff & grid[n + 2])) - defaultColB; if (b < 0) b = 0;
- grid[n ] = (byte) r;
- grid[n + 1] = (byte) g;
- grid[n + 2] = (byte) b;
- }
- }
-
-
- protected void line(int Ax, int Ay, int Bx, int By) {
- // Bresenham's line drawing algorithm
- int dX = Math.abs(Bx-Ax);
- int dY = Math.abs(By-Ay);
- int Xincr, Yincr;
- if (Ax > Bx) Xincr=-1; else Xincr=1;
- if (Ay > By) Yincr=-1; else Yincr=1;
- if (dX >= dY) {
- int dPr = dY<<1;
- int dPru = dPr - (dX<<1);
- int P = dPr - dX;
- for (; dX>=0; dX--) {
- plot(Ax, Ay);
- if (P > 0) {
- Ax+=Xincr;
- Ay+=Yincr;
- P+=dPru;
- } else {
- Ax+=Xincr;
- P+=dPr;
- }
- }
- } else {
- int dPr = dX<<1;
- int dPru = dPr - (dY<<1);
- int P = dPr - dY;
- for (; dY>=0; dY--) {
- plot(Ax, Ay);
- if (P > 0) {
- Ax+=Xincr;
- Ay+=Yincr;
- P+=dPru;
- } else {
- Ay+=Yincr;
- P+=dPr;
- }
- }
- }
- }
-
- private static int[] getCircleCoords(int radius) {
- if ((radius - 1) < circles.length) return circles[radius - 1];
-
- // read some lines from known circles
- HashSet crds = new HashSet();
- crds.add("0|0");
- String co;
- for (int i = Math.max(0, circles.length - 5); i < circles.length; i++) {
- for (int j = 0; j < circles[i].length; j = j + 2) {
- co = circles[i][j] + "|" + circles[i][j + 1];
- if (!(crds.contains(co))) crds.add(co);
- }
- }
-
- // copy old circles into new array
- int[][] newCircles = new int[radius + 30][];
- System.arraycopy(circles, 0, newCircles, 0, circles.length);
-
- // compute more lines in new circles
- int x, y;
- ArrayList crc;
- for (int r = circles.length; r < newCircles.length; r++) {
- crc = new ArrayList();
- for (int a = 0; a <= 2 * (r + 1); a++) {
- x = (int) ((r + 1) * Math.cos(Math.PI * a / (4 * (r + 1))));
- y = (int) ((r + 1) * Math.sin(Math.PI * a / (4 * (r + 1))));
- co = x + "|" + y;
- if (!(crds.contains(co))) {
- crc.add(new int[]{x, y});
- crds.add(co);
- }
- x = (int) ((r + 0.5) * Math.cos(Math.PI * a / (4 * (r + 1))));
- y = (int) ((r + 0.5) * Math.sin(Math.PI * a / (4 * (r + 1))));
- co = x + "|" + y;
- if (!(crds.contains(co))) {
- crc.add(new int[]{x, y});
- crds.add(co);
- }
- }
- // put coordinates into array
- //System.out.print("Radius " + r + " => " + crc.size() + " points: ");
- newCircles[r] = new int[2 * (crc.size() - 1)];
- int[] coords;
- for (int i = 0; i < crc.size() - 1; i++) {
- coords = (int[]) crc.get(i);
- newCircles[r][2 * i ] = coords[0];
- newCircles[r][2 * i + 1] = coords[1];
- //System.out.print(circles[r][i][0] + "," +circles[r][i][1] + "; ");
- }
- //System.out.println();
- }
- crc = null;
- crds = null;
-
- // move newCircles to circles array
- circles = newCircles;
- newCircles = null;
-
- // finally return wanted slice
- return circles[radius - 1];
- }
-
- private void circle(int xc, int yc, int radius) {
- if (radius == 0) {
- plot(xc, yc);
- } else {
- int[] c = getCircleCoords(radius);
- int x, y;
- for (int i = (c.length / 2) - 1; i >= 0; i--) {
- x = c[2 * i ];
- y = c[2 * i + 1];
- plot(xc + x , yc - y - 1); // quadrant 1
- plot(xc - x + 1, yc - y - 1); // quadrant 2
- plot(xc + x , yc + y ); // quadrant 4
- plot(xc - x + 1, yc + y ); // quadrant 3
- }
- }
- }
-
- private void circle(int xc, int yc, int radius, int fromArc, int toArc) {
- // draws only a part of a circle
- // arc is given in degree
- if (radius == 0) {
- plot(xc, yc);
- } else {
- int[] c = getCircleCoords(radius);
- int q = c.length / 2;
- int[][] c4 = new int[q * 4][];
- for (int i = 0; i < q; i++) {
- c4[i ] = new int[]{ c[2 * (i )], -c[2 * (i ) + 1] - 1}; // quadrant 1
- c4[i + q] = new int[]{1 - c[2 * (q - 1 - i)], -c[2 * (q - 1 - i) + 1] - 1}; // quadrant 2
- c4[i + 2 * q] = new int[]{1 - c[2 * (i )], c[2 * (i ) + 1] }; // quadrant 3
- c4[i + 3 * q] = new int[]{ c[2 * (q - 1 - i)], c[2 * (q - 1 - i) + 1] }; // quadrant 4
- }
- for (int i = q * 4 * fromArc / 360; i < q * 4 * toArc / 360; i++) {
- plot(xc + c4[i][0], yc + c4[i][1]);
- }
- }
- }
-
- public void dot(int x, int y, int radius, boolean filled) {
- if (filled) {
- for (int r = radius; r >= 0; r--) circle(x, y, r);
- } else {
- circle(x, y, radius);
- }
- }
-
- public void arc(int x, int y, int innerRadius, int outerRadius, int fromArc, int toArc) {
- for (int r = innerRadius; r <= outerRadius; r++) circle(x, y, r, fromArc, toArc);
-
- }
-
- private void print(int x, int y, int angle, char letter) {
- int index = (int) letter - 0x20;
- if (index >= font.length) return;
- long character = font[index];
- long row;
- for (int i = 0; i < 5; i++) {
- row = character & 0x1f;
- character = character >> 5;
- if (angle == 0) {
- for (int j = 0; j < 5; j++) {
- if ((row & 1) == 1) plot(x + 5 - j, y);
- row = row >> 1;
- }
- y--;
- }
- if (angle == 90) {
- for (int j = 0; j < 5; j++) {
- if ((row & 1) == 1) plot(x, y - 5 + j);
- row = row >> 1;
- }
- x--;
- }
- }
- }
-
- public void print(int x, int y, int angle, String message, boolean alignLeft) {
- int xx = 0, yy = 0;
- if (angle == 0) {
- xx = (alignLeft) ? x : x - 6 * message.length();
- yy = y;
- } else if (angle == 90) {
- xx = x;
- yy = (alignLeft) ? y : y + 6 * message.length();
- }
- for (int i = 0; i < message.length(); i++) {
- print(xx, yy, angle, message.charAt(i));
- if (angle == 0) xx += 6;
- else if (angle == 90) yy -= 6;
- }
- }
-
- private static final int arcDist = 8;
- public void arcPrint(int cx, int cy, int radius, int angle, String message) {
- int x = cx + (int) ((radius + 1) * Math.cos(Math.PI * angle / 180));
- int y = cy - (int) ((radius + 1) * Math.sin(Math.PI * angle / 180));
- int yp = y + 3;
- if ((angle > arcDist) && (angle < 180 - arcDist)) yp = y;
- if ((angle > 180 + arcDist) && (angle < 360 - arcDist)) yp = y + 6;
- if ((angle > ( 90 - arcDist)) && (angle < ( 90 + arcDist))) yp -= 6;
- if ((angle > (270 - arcDist)) && (angle < (270 + arcDist))) yp += 6;
- int xp = x - 3 * message.length();
- if ((angle > (90 + arcDist)) && (angle < (270 - arcDist))) xp = x - 6 * message.length();
- if ((angle < (90 - arcDist)) || (angle > (270 + arcDist))) xp = x;
- print(xp, yp, 0, message, true);
- }
-
- public void arcLine(int cx, int cy, int innerRadius, int outerRadius, int angle) {
- int xi = cx + (int) (innerRadius * Math.cos(Math.PI * angle / 180));
- int yi = cy - (int) (innerRadius * Math.sin(Math.PI * angle / 180));
- int xo = cx + (int) (outerRadius * Math.cos(Math.PI * angle / 180));
- int yo = cy - (int) (outerRadius * Math.sin(Math.PI * angle / 180));
- line(xi, yi, xo, yo);
- }
-
- public void arcDot(int cx, int cy, int arcRadius, int angle, int dotRadius) {
- int x = cx + (int) (arcRadius * Math.cos(Math.PI * angle / 180));
- int y = cy - (int) (arcRadius * Math.sin(Math.PI * angle / 180));
- dot(x, y, dotRadius, true);
- }
-
- public void arcArc(int cx, int cy, int arcRadius, int angle, int innerRadius, int outerRadius, int fromArc, int toArc) {
- int x = cx + (int) (arcRadius * Math.cos(Math.PI * angle / 180));
- int y = cy - (int) (arcRadius * Math.sin(Math.PI * angle / 180));
- arc(x, y, innerRadius, outerRadius, fromArc, toArc);
- }
-
-
- public BufferedImage toImage(boolean complementary) {
- /*
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice gs = ge.getDefaultScreenDevice();
- GraphicsConfiguration gc = gs.getDefaultConfiguration();
- BufferedImage bi = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
- */
- try {
- BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics2D gr = bi.createGraphics();
- gr.setBackground(Color.white);
- gr.clearRect(0, 0, width, height);
-
- WritableRaster wr = bi.getRaster();
- int n;
- int r, g, b;
- if (complementary) {
- // then set pixels
- for (int i = width - 1; i >= 0; i--) {
- for (int j = height - 1; j >= 0; j--) {
- n = 3 * (i + j * width);
- r = 0xff & grid[n ];
- g = 0xff & grid[n + 1];
- b = 0xff & grid[n + 2];
- wr.setPixel(i, j, new int[]{(0x1fe - g - b) / 2, (0x1fe - r - b) / 2, (0x1fe - r - g) / 2});
- }
- }
- } else {
- for (int i = width - 1; i >= 0; i--) {
- for (int j = height - 1; j >= 0; j--) {
- n = 3 * (i + j * width);
- r = 0xff & grid[n ];
- g = 0xff & grid[n + 1];
- b = 0xff & grid[n + 2];
- wr.setPixel(i, j, new int[]{r, g, b});
- }
- }
- }
- return bi;
- } catch (Exception e) {
- // strange case where environment disallowes generation of graphics
- /*
- java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
- at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
- at sun.awt.X11GraphicsEnvironment.access$000(X11GraphicsEnvironment.java:53)
- at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:142)
- at java.security.AccessController.doPrivileged(Native Method)
- at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:131)
- at java.lang.Class.forName0(Native Method)
- at java.lang.Class.forName(Class.java:164)
- at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:68)
- at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1141)
- at de.anomic.tools.ImagePainter.toImage(ImagePainter.java:354)
- */
- System.out.println("Error with Graphics environment:");
- e.printStackTrace();
- return new BufferedImage(0, 0, BufferedImage.TYPE_INT_RGB);
- }
- }
-
- public void toPNG(boolean complementary, File f) throws IOException {
- BufferedImage bi = toImage(complementary);
- ImageIO.write(bi, "png", f);
- }
-
-
-
-}
+// ymageMatrixPainter.java
+// ---------------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2005
+// created: 31.10.2005
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+package de.anomic.ymage;
+
+import java.util.HashSet;
+import java.util.ArrayList;
+
+public class ymageMatrixPainter extends ymageMatrix implements ymagePainter {
+
+ private static long[] font = new long[]{
+ 0x0000000,0x0421004,0x0A50000,0x0AFABEA,0x0FA38BE,0x09B39B2,0x0E82A8A,0x0420000,
+ 0x0221082,0x0821080,0x0051040,0x0023880,0x0001088,0x0003800,0x0000004,0x0111110,
+ 0x0E9D72E,0x046108E,0x0E8991F,0x0E88A2E,0x0657C42,0x1F8783E,0x0E87A2E,0x1F11084,
+ 0x0E8BA2E,0x0E8BC2E,0x0020080,0x0020088,0x0222082,0x00F83E0,0x0820888,0x0E11004,
+ 0x0EEFA0E,0x04547F1,0x1C97A3E,0x0E8420E,0x1E8C63E,0x1F8721F,0x1F87210,0x0E85E2E,
+ 0x118FE31,0x1F2109F,0x1F0862E,0x1197251,0x108421F,0x11DD631,0x11CD671,0x0E8C62E,
+ 0x1E8FA10,0x0E8D64D,0x1E8FA51,0x0E8382E,0x1F21084,0x118C62E,0x118C544,0x118C6AA,
+ 0x1151151,0x1151084,0x1F1111F,0x0E4210E,0x1041041,0x0E1084E,0x0454400,0x000001F,
+ 0x0820000,0x0003E2F,0x1087A3E,0x0003E0F,0x010BE2F,0x0064A8F,0x0623884,0x00324BE,
+ 0x1085B31,0x0401084,0x0401088,0x1084F93,0x0421084,0x0002AB5,0x0003A31,0x0003A2E,
+ 0x00F47D0,0x007C5E1,0x0011084,0x0001932,0x0471084,0x000462E,0x0004544,0x00056AA,
+ 0x000288A,0x0002884,0x0003C9E,0x0622086,0x0421084,0x0C2088C,0x0045440,0x1F8C63F
+ };
+
+ private static int[][] circles = new int[0][];
+
+ public ymageMatrixPainter(int width, int height, String backgroundColor) {
+ super(width, height, backgroundColor);
+ }
+
+ private static int[] getCircleCoords(int radius) {
+ if ((radius - 1) < circles.length) return circles[radius - 1];
+
+ // read some lines from known circles
+ HashSet crds = new HashSet();
+ crds.add("0|0");
+ String co;
+ for (int i = Math.max(0, circles.length - 5); i < circles.length; i++) {
+ for (int j = 0; j < circles[i].length; j = j + 2) {
+ co = circles[i][j] + "|" + circles[i][j + 1];
+ if (!(crds.contains(co))) crds.add(co);
+ }
+ }
+
+ // copy old circles into new array
+ int[][] newCircles = new int[radius + 30][];
+ System.arraycopy(circles, 0, newCircles, 0, circles.length);
+
+ // compute more lines in new circles
+ int x, y;
+ ArrayList crc;
+ for (int r = circles.length; r < newCircles.length; r++) {
+ crc = new ArrayList();
+ for (int a = 0; a <= 2 * (r + 1); a++) {
+ x = (int) ((r + 1) * Math.cos(Math.PI * a / (4 * (r + 1))));
+ y = (int) ((r + 1) * Math.sin(Math.PI * a / (4 * (r + 1))));
+ co = x + "|" + y;
+ if (!(crds.contains(co))) {
+ crc.add(new int[]{x, y});
+ crds.add(co);
+ }
+ x = (int) ((r + 0.5) * Math.cos(Math.PI * a / (4 * (r + 1))));
+ y = (int) ((r + 0.5) * Math.sin(Math.PI * a / (4 * (r + 1))));
+ co = x + "|" + y;
+ if (!(crds.contains(co))) {
+ crc.add(new int[]{x, y});
+ crds.add(co);
+ }
+ }
+ // put coordinates into array
+ //System.out.print("Radius " + r + " => " + crc.size() + " points: ");
+ newCircles[r] = new int[2 * (crc.size() - 1)];
+ int[] coords;
+ for (int i = 0; i < crc.size() - 1; i++) {
+ coords = (int[]) crc.get(i);
+ newCircles[r][2 * i ] = coords[0];
+ newCircles[r][2 * i + 1] = coords[1];
+ //System.out.print(circles[r][i][0] + "," +circles[r][i][1] + "; ");
+ }
+ //System.out.println();
+ }
+ crc = null;
+ crds = null;
+
+ // move newCircles to circles array
+ circles = newCircles;
+ newCircles = null;
+
+ // finally return wanted slice
+ return circles[radius - 1];
+ }
+
+ public void circle(int xc, int yc, int radius) {
+ if (radius == 0) {
+ plot(xc, yc);
+ } else {
+ int[] c = getCircleCoords(radius);
+ int x, y;
+ for (int i = (c.length / 2) - 1; i >= 0; i--) {
+ x = c[2 * i ];
+ y = c[2 * i + 1];
+ plot(xc + x , yc - y - 1); // quadrant 1
+ plot(xc - x + 1, yc - y - 1); // quadrant 2
+ plot(xc + x , yc + y ); // quadrant 4
+ plot(xc - x + 1, yc + y ); // quadrant 3
+ }
+ }
+ }
+
+ public void circle(int xc, int yc, int radius, int fromArc, int toArc) {
+ // draws only a part of a circle
+ // arc is given in degree
+ if (radius == 0) {
+ plot(xc, yc);
+ } else {
+ int[] c = getCircleCoords(radius);
+ int q = c.length / 2;
+ int[][] c4 = new int[q * 4][];
+ for (int i = 0; i < q; i++) {
+ c4[i ] = new int[]{ c[2 * (i )], -c[2 * (i ) + 1] - 1}; // quadrant 1
+ c4[i + q] = new int[]{1 - c[2 * (q - 1 - i)], -c[2 * (q - 1 - i) + 1] - 1}; // quadrant 2
+ c4[i + 2 * q] = new int[]{1 - c[2 * (i )], c[2 * (i ) + 1] }; // quadrant 3
+ c4[i + 3 * q] = new int[]{ c[2 * (q - 1 - i)], c[2 * (q - 1 - i) + 1] }; // quadrant 4
+ }
+ for (int i = q * 4 * fromArc / 360; i < q * 4 * toArc / 360; i++) {
+ plot(xc + c4[i][0], yc + c4[i][1]);
+ }
+ }
+ }
+
+ public void dot(int x, int y, int radius, boolean filled) {
+ if (filled) {
+ for (int r = radius; r >= 0; r--) circle(x, y, r);
+ } else {
+ circle(x, y, radius);
+ }
+ }
+
+ public void arc(int x, int y, int innerRadius, int outerRadius, int fromArc, int toArc) {
+ for (int r = innerRadius; r <= outerRadius; r++) circle(x, y, r, fromArc, toArc);
+
+ }
+
+ private void print(int x, int y, int angle, char letter) {
+ int index = (int) letter - 0x20;
+ if (index >= font.length) return;
+ long character = font[index];
+ long row;
+ for (int i = 0; i < 5; i++) {
+ row = character & 0x1f;
+ character = character >> 5;
+ if (angle == 0) {
+ for (int j = 0; j < 5; j++) {
+ if ((row & 1) == 1) plot(x + 5 - j, y);
+ row = row >> 1;
+ }
+ y--;
+ }
+ if (angle == 90) {
+ for (int j = 0; j < 5; j++) {
+ if ((row & 1) == 1) plot(x, y - 5 + j);
+ row = row >> 1;
+ }
+ x--;
+ }
+ }
+ }
+
+ public void print(int x, int y, int angle, String message, boolean alignLeft) {
+ int xx = 0, yy = 0;
+ if (angle == 0) {
+ xx = (alignLeft) ? x : x - 6 * message.length();
+ yy = y;
+ } else if (angle == 90) {
+ xx = x;
+ yy = (alignLeft) ? y : y + 6 * message.length();
+ }
+ for (int i = 0; i < message.length(); i++) {
+ print(xx, yy, angle, message.charAt(i));
+ if (angle == 0) xx += 6;
+ else if (angle == 90) yy -= 6;
+ }
+ }
+
+ private static final int arcDist = 8;
+ public void arcPrint(int cx, int cy, int radius, int angle, String message) {
+ int x = cx + (int) ((radius + 1) * Math.cos(Math.PI * angle / 180));
+ int y = cy - (int) ((radius + 1) * Math.sin(Math.PI * angle / 180));
+ int yp = y + 3;
+ if ((angle > arcDist) && (angle < 180 - arcDist)) yp = y;
+ if ((angle > 180 + arcDist) && (angle < 360 - arcDist)) yp = y + 6;
+ if ((angle > ( 90 - arcDist)) && (angle < ( 90 + arcDist))) yp -= 6;
+ if ((angle > (270 - arcDist)) && (angle < (270 + arcDist))) yp += 6;
+ int xp = x - 3 * message.length();
+ if ((angle > (90 + arcDist)) && (angle < (270 - arcDist))) xp = x - 6 * message.length();
+ if ((angle < (90 - arcDist)) || (angle > (270 + arcDist))) xp = x;
+ print(xp, yp, 0, message, true);
+ }
+
+ public void arcLine(int cx, int cy, int innerRadius, int outerRadius, int angle) {
+ int xi = cx + (int) (innerRadius * Math.cos(Math.PI * angle / 180));
+ int yi = cy - (int) (innerRadius * Math.sin(Math.PI * angle / 180));
+ int xo = cx + (int) (outerRadius * Math.cos(Math.PI * angle / 180));
+ int yo = cy - (int) (outerRadius * Math.sin(Math.PI * angle / 180));
+ line(xi, yi, xo, yo);
+ }
+
+ public void arcDot(int cx, int cy, int arcRadius, int angle, int dotRadius) {
+ int x = cx + (int) (arcRadius * Math.cos(Math.PI * angle / 180));
+ int y = cy - (int) (arcRadius * Math.sin(Math.PI * angle / 180));
+ dot(x, y, dotRadius, true);
+ }
+
+ public void arcArc(int cx, int cy, int arcRadius, int angle, int innerRadius, int outerRadius, int fromArc, int toArc) {
+ int x = cx + (int) (arcRadius * Math.cos(Math.PI * angle / 180));
+ int y = cy - (int) (arcRadius * Math.sin(Math.PI * angle / 180));
+ arc(x, y, innerRadius, outerRadius, fromArc, toArc);
+ }
+
+}
diff --git a/source/de/anomic/ymage/ymagePNGEncoderAWT.java b/source/de/anomic/ymage/ymagePNGEncoderAWT.java
new file mode 100644
index 000000000..85b2692f6
--- /dev/null
+++ b/source/de/anomic/ymage/ymagePNGEncoderAWT.java
@@ -0,0 +1,93 @@
+// ymagePNGEncoderAWT.java
+// ---------------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2005
+// created: 31.10.2005
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+package de.anomic.ymage;
+
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsConfiguration;
+import java.awt.Transparency;
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import javax.imageio.ImageIO;
+import java.io.File;
+import java.io.IOException;
+
+public class ymagePNGEncoderAWT {
+
+
+ public static BufferedImage toImage(ymageMatrix matrix, boolean complementary) {
+ // GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ // GraphicsDevice gs = ge.getDefaultScreenDevice();
+ // GraphicsConfiguration gc = gs.getDefaultConfiguration();
+ // BufferedImage bi = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
+ try {
+ BufferedImage bi = new BufferedImage(matrix.getWidth(), matrix.getHeight(), BufferedImage.TYPE_INT_RGB);
+ Graphics2D gr = bi.createGraphics();
+ gr.setBackground(Color.white);
+ gr.clearRect(0, 0, matrix.getWidth(), matrix.getHeight());
+
+ WritableRaster wr = bi.getRaster();
+ int n;
+ int r, g, b;
+ matrix.getColorMode(complementary);
+ for (int i = matrix.getWidth() - 1; i >= 0; i--) {
+ for (int j = matrix.getHeight() - 1; j >= 0; j--) {
+ wr.setPixel(i, j, matrix.getColor(i, j));
+ }
+ }
+ return bi;
+ } catch (Exception e) {
+ // strange case where environment disallowes generation of graphics
+
+ System.out.println("Error with Graphics environment:");
+ e.printStackTrace();
+ return new BufferedImage(0, 0, BufferedImage.TYPE_INT_RGB);
+ }
+ }
+
+ public static void toPNG(ymageMatrix matrix, boolean complementary, File f) throws IOException {
+ BufferedImage bi = toImage(matrix, complementary);
+ ImageIO.write(bi, "png", f);
+ }
+
+}
diff --git a/source/de/anomic/ymage/ymagePNGEncoderJDE.java b/source/de/anomic/ymage/ymagePNGEncoderJDE.java
new file mode 100644
index 000000000..6d7c7b444
--- /dev/null
+++ b/source/de/anomic/ymage/ymagePNGEncoderJDE.java
@@ -0,0 +1,552 @@
+/**
+ * PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file.
+ * The Image is presumed to use the DirectColorModel.
+ *
+ * Thanks to Jay Denny at KeyPoint Software
+ * http://www.keypoint.com/
+ * who let me develop this code on company time.
+ *
+ * You may contact me with (probably very-much-needed) improvements,
+ * comments, and bug fixes at:
+ *
+ * david@catcode.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * A copy of the GNU LGPL may be found at
+ * http://www.gnu.org/copyleft/lesser.html,
+ *
+ * @author J. David Eisenberg
+ * @version 1.4, 31 March 2000
+ */
+
+/*
+ * this file was taken from
+ * http://chem.sis.nlm.nih.gov/chemidplus/applet/chemaxon/marvin/help/PngEncoder.java.txt
+ * and modified by Michael Peter Christen, Frankfurt, 2005
+ * to work with ImagePainter Objects instead of awt.image Objetcs
+ * this avoids using any awt routines
+ */
+
+package de.anomic.ymage;
+
+import java.util.*;
+import java.util.zip.*;
+import java.io.*;
+
+public class ymagePNGEncoderJDE extends Object
+{
+ /** Constants for filters */
+ public static final int FILTER_NONE = 0;
+ public static final int FILTER_SUB = 1;
+ public static final int FILTER_UP = 2;
+ public static final int FILTER_LAST = 2;
+
+ protected byte[] pngBytes;
+ protected byte[] priorRow;
+ protected byte[] leftBytes;
+ protected ymageMatrix matrix;
+ protected int width, height;
+ protected int bytePos, maxPos;
+ protected int hdrPos, dataPos, endPos;
+ protected CRC32 crc = new CRC32();
+ protected long crcValue;
+ protected boolean encodeAlpha;
+ protected int filter;
+ protected int bytesPerPixel;
+ protected int compressionLevel;
+
+ /**
+ * Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.
+ *
+ * @param image A Java Image object
+ * @param encodeAlpha Encode the alpha channel? false=no; true=yes
+ * @param whichFilter 0=none, 1=sub, 2=up
+ * @param compLevel 0..9
+ * @see java.awt.Image
+ */
+ public ymagePNGEncoderJDE(ymageMatrix matrix, int whichFilter, int compLevel)
+ {
+ this.matrix = matrix;
+ this.encodeAlpha = false;
+ setFilter( whichFilter );
+ if (compLevel >=0 && compLevel <=9)
+ {
+ this.compressionLevel = compLevel;
+ }
+ }
+
+
+ /**
+ * Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
+ *
+ * @param encodeAlpha boolean false=no alpha, true=encode alpha
+ * @return an array of bytes, or null if there was a problem
+ */
+ public byte[] pngEncode( boolean encodeAlpha )
+ {
+ byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
+ int i;
+
+ if (matrix == null)
+ {
+ return null;
+ }
+ width = matrix.getWidth();
+ height = matrix.getHeight();
+ this.matrix = matrix;
+
+ /*
+ * start with an array that is big enough to hold all the pixels
+ * (plus filter bytes), and an extra 200 bytes for header info
+ */
+ pngBytes = new byte[((width+1) * height * 3) + 200];
+
+ /*
+ * keep track of largest byte written to the array
+ */
+ maxPos = 0;
+
+ bytePos = writeBytes( pngIdBytes, 0 );
+ hdrPos = bytePos;
+ writeHeader();
+ dataPos = bytePos;
+ if (writeImageData())
+ {
+ writeEnd();
+ pngBytes = resizeByteArray( pngBytes, maxPos );
+ }
+ else
+ {
+ pngBytes = null;
+ }
+ return pngBytes;
+ }
+
+ /**
+ * Creates an array of bytes that is the PNG equivalent of the current image.
+ * Alpha encoding is determined by its setting in the constructor.
+ *
+ * @return an array of bytes, or null if there was a problem
+ */
+ public byte[] pngEncode()
+ {
+ return pngEncode( encodeAlpha );
+ }
+
+ /**
+ * Set the alpha encoding on or off.
+ *
+ * @param encodeAlpha false=no, true=yes
+ */
+ public void setEncodeAlpha( boolean encodeAlpha )
+ {
+ this.encodeAlpha = encodeAlpha;
+ }
+
+ /**
+ * Retrieve alpha encoding status.
+ *
+ * @return boolean false=no, true=yes
+ */
+ public boolean getEncodeAlpha()
+ {
+ return encodeAlpha;
+ }
+
+ /**
+ * Set the filter to use
+ *
+ * @param whichFilter from constant list
+ */
+ public void setFilter( int whichFilter )
+ {
+ this.filter = FILTER_NONE;
+ if ( whichFilter <= FILTER_LAST )
+ {
+ this.filter = whichFilter;
+ }
+ }
+
+ /**
+ * Retrieve filtering scheme
+ *
+ * @return int (see constant list)
+ */
+ public int getFilter()
+ {
+ return filter;
+ }
+
+ /**
+ * Set the compression level to use
+ *
+ * @param level 0 through 9
+ */
+ public void setCompressionLevel( int level )
+ {
+ if ( level >= 0 && level <= 9)
+ {
+ this.compressionLevel = level;
+ }
+ }
+
+ /**
+ * Retrieve compression level
+ *
+ * @return int in range 0-9
+ */
+ public int getCompressionLevel()
+ {
+ return compressionLevel;
+ }
+
+ /**
+ * Increase or decrease the length of a byte array.
+ *
+ * @param array The original array.
+ * @param newLength The length you wish the new array to have.
+ * @return Array of newly desired length. If shorter than the
+ * original, the trailing elements are truncated.
+ */
+ protected byte[] resizeByteArray( byte[] array, int newLength )
+ {
+ byte[] newArray = new byte[newLength];
+ int oldLength = array.length;
+
+ System.arraycopy( array, 0, newArray, 0,
+ Math.min( oldLength, newLength ) );
+ return newArray;
+ }
+
+ /**
+ * Write an array of bytes into the pngBytes array.
+ * Note: This routine has the side effect of updating
+ * maxPos, the largest element written in the array.
+ * The array is resized by 1000 bytes or the length
+ * of the data to be written, whichever is larger.
+ *
+ * @param data The data to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int writeBytes( byte[] data, int offset )
+ {
+ maxPos = Math.max( maxPos, offset + data.length );
+ if (data.length + offset > pngBytes.length)
+ {
+ pngBytes = resizeByteArray( pngBytes, pngBytes.length +
+ Math.max( 1000, data.length ) );
+ }
+ System.arraycopy( data, 0, pngBytes, offset, data.length );
+ return offset + data.length;
+ }
+
+ /**
+ * Write an array of bytes into the pngBytes array, specifying number of bytes to write.
+ * Note: This routine has the side effect of updating
+ * maxPos, the largest element written in the array.
+ * The array is resized by 1000 bytes or the length
+ * of the data to be written, whichever is larger.
+ *
+ * @param data The data to be written into pngBytes.
+ * @param nBytes The number of bytes to be written.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int writeBytes( byte[] data, int nBytes, int offset )
+ {
+ maxPos = Math.max( maxPos, offset + nBytes );
+ if (nBytes + offset > pngBytes.length)
+ {
+ pngBytes = resizeByteArray( pngBytes, pngBytes.length +
+ Math.max( 1000, nBytes ) );
+ }
+ System.arraycopy( data, 0, pngBytes, offset, nBytes );
+ return offset + nBytes;
+ }
+
+ /**
+ * Write a two-byte integer into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int writeInt2( int n, int offset )
+ {
+ byte[] temp = { (byte)((n >> 8) & 0xff),
+ (byte) (n & 0xff) };
+ return writeBytes( temp, offset );
+ }
+
+ /**
+ * Write a four-byte integer into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int writeInt4( int n, int offset )
+ {
+ byte[] temp = { (byte)((n >> 24) & 0xff),
+ (byte) ((n >> 16) & 0xff ),
+ (byte) ((n >> 8) & 0xff ),
+ (byte) ( n & 0xff ) };
+ return writeBytes( temp, offset );
+ }
+
+ /**
+ * Write a single byte into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int writeByte( int b, int offset )
+ {
+ byte[] temp = { (byte) b };
+ return writeBytes( temp, offset );
+ }
+
+ /**
+ * Write a string into the pngBytes array at a given position.
+ * This uses the getBytes method, so the encoding used will
+ * be its default.
+ *
+ * @param n The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ * @see java.lang.String#getBytes()
+ */
+ protected int writeString( String s, int offset )
+ {
+ return writeBytes( s.getBytes(), offset );
+ }
+
+ /**
+ * Write a PNG "IHDR" chunk into the pngBytes array.
+ */
+ protected void writeHeader()
+ {
+ int startPos;
+
+ startPos = bytePos = writeInt4( 13, bytePos );
+ bytePos = writeString( "IHDR", bytePos );
+ width = matrix.getWidth();
+ height = matrix.getHeight();
+ bytePos = writeInt4( width, bytePos );
+ bytePos = writeInt4( height, bytePos );
+ bytePos = writeByte( 8, bytePos ); // bit depth
+ bytePos = writeByte( (encodeAlpha) ? 6 : 2, bytePos ); // direct model
+ bytePos = writeByte( 0, bytePos ); // compression method
+ bytePos = writeByte( 0, bytePos ); // filter method
+ bytePos = writeByte( 0, bytePos ); // no interlace
+ crc.reset();
+ crc.update( pngBytes, startPos, bytePos-startPos );
+ crcValue = crc.getValue();
+ bytePos = writeInt4( (int) crcValue, bytePos );
+ }
+
+ /**
+ * Perform "sub" filtering on the given row.
+ * Uses temporary array leftBytes to store the original values
+ * of the previous pixels. The array is 16 bytes long, which
+ * will easily hold two-byte samples plus two-byte alpha.
+ *
+ * @param pixels The array holding the scan lines being built
+ * @param startPos Starting position within pixels of bytes to be filtered.
+ * @param width Width of a scanline in pixels.
+ */
+ protected void filterSub( byte[] pixels, int startPos, int width )
+ {
+ int i;
+ int offset = bytesPerPixel;
+ int actualStart = startPos + offset;
+ int nBytes = width * bytesPerPixel;
+ int leftInsert = offset;
+ int leftExtract = 0;
+ byte current_byte;
+
+ for (i=actualStart; i < startPos + nBytes; i++)
+ {
+ leftBytes[leftInsert] = pixels[i];
+ pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
+ leftInsert = (leftInsert+1) % 0x0f;
+ leftExtract = (leftExtract + 1) % 0x0f;
+ }
+ }
+
+ /**
+ * Perform "up" filtering on the given row.
+ * Side effect: refills the prior row with current row
+ *
+ * @param pixels The array holding the scan lines being built
+ * @param startPos Starting position within pixels of bytes to be filtered.
+ * @param width Width of a scanline in pixels.
+ */
+ protected void filterUp( byte[] pixels, int startPos, int width )
+ {
+ int i, nBytes;
+ byte current_byte;
+
+ nBytes = width * bytesPerPixel;
+
+ for (i=0; i < nBytes; i++)
+ {
+ current_byte = pixels[startPos + i];
+ pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
+ priorRow[i] = current_byte;
+ }
+ }
+
+ /**
+ * 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 boolean 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 );
+ ByteArrayOutputStream outBytes =
+ new ByteArrayOutputStream(1024);
+
+ DeflaterOutputStream compBytes =
+ new DeflaterOutputStream( outBytes, scrunch );
+ try
+ {
+ while (rowsLeft > 0)
+ {
+
+ nRows = Math.min( 32767 / (width*(bytesPerPixel+1)), rowsLeft );
+ // nRows = rowsLeft;
+
+ /*
+ * 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;
+ int[] pixel;
+ matrix.getColorMode(true);
+ for (int i=0; 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.toByteArray();
+ nCompressed = compressedLines.length;
+
+ crc.reset();
+ bytePos = writeInt4( nCompressed, bytePos );
+ bytePos = writeString("IDAT", bytePos );
+ crc.update("IDAT".getBytes());
+ bytePos = writeBytes( compressedLines, nCompressed, bytePos );
+ crc.update( compressedLines, 0, nCompressed );
+
+ crcValue = crc.getValue();
+ bytePos = writeInt4( (int) crcValue, bytePos );
+ scrunch.finish();
+ return true;
+ }
+ catch (IOException e)
+ {
+ System.err.println( e.toString());
+ return false;
+ } finally {
+ }
+ }
+
+ /**
+ * Write a PNG "IEND" chunk into the pngBytes array.
+ */
+ protected void writeEnd()
+ {
+ bytePos = writeInt4( 0, bytePos );
+ bytePos = writeString( "IEND", bytePos );
+ crc.reset();
+ crc.update("IEND".getBytes());
+ crcValue = crc.getValue();
+ bytePos = writeInt4( (int) crcValue, bytePos );
+ }
+}
diff --git a/source/de/anomic/ymage/ymagePainter.java b/source/de/anomic/ymage/ymagePainter.java
new file mode 100644
index 000000000..301000bd4
--- /dev/null
+++ b/source/de/anomic/ymage/ymagePainter.java
@@ -0,0 +1,80 @@
+// ymagePainter.java
+// ---------------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2005
+// created: 31.10.2005
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+package de.anomic.ymage;
+
+
+public interface ymagePainter {
+
+ public Object clone();
+
+ public int getWidth();
+
+ public int getHeight();
+
+ public void setColor(String s);
+
+ public void setColor(long c);
+
+ public void setMode(byte m);
+
+ public void plot(int x, int y);
+
+ public void line(int Ax, int Ay, int Bx, int By);
+
+ public void circle(int xc, int yc, int radius);
+
+ public void circle(int xc, int yc, int radius, int fromArc, int toArc);
+
+ public void dot(int x, int y, int radius, boolean filled);
+
+ public void arc(int x, int y, int innerRadius, int outerRadius, int fromArc, int toArc);
+
+ public void print(int x, int y, int angle, String message, boolean alignLeft);
+
+ public void arcPrint(int cx, int cy, int radius, int angle, String message);
+
+ public void arcLine(int cx, int cy, int innerRadius, int outerRadius, int angle);
+
+ public void arcDot(int cx, int cy, int arcRadius, int angle, int dotRadius);
+
+ public void arcArc(int cx, int cy, int arcRadius, int angle, int innerRadius, int outerRadius, int fromArc, int toArc);
+
+}