forked from I2P_Developers/i2p.i2p
Compare commits
11 Commits
i2p-2.5.1-
...
i2p-2.5.1-
Author | SHA1 | Date | |
---|---|---|---|
e1620742b3 | |||
4fa1965b11 | |||
4e9ac43b55 | |||
177fbad865 | |||
84dbf53f95 | |||
3f2bfe8871 | |||
603bca476a | |||
b3fc35541c | |||
44190bb52d | |||
2facca2308 | |||
7cf9daa381 |
4
.github/workflows/ant.yml
vendored
4
.github/workflows/ant.yml
vendored
@ -56,8 +56,6 @@ jobs:
|
||||
echo "noExe=true" >> override.properties
|
||||
- name: test Debian build with Ant
|
||||
run: ant distclean
|
||||
- name: build mavenCentral deps with Ant
|
||||
run: ant mavenCentral.deps
|
||||
- name: build javadoc with Ant
|
||||
run: ant distclean javadoc updater
|
||||
- name: zip javadoc
|
||||
@ -95,8 +93,6 @@ jobs:
|
||||
echo "build.built-by=GitHub Actions" >> override.properties
|
||||
echo "noExe=true" >> override.properties
|
||||
echo "javac.compilerargs=-bootclasspath $HOME/openjdk-7/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar:$HOME/openjdk-7/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jce.jar -Xlint:all" >> override.properties
|
||||
- name: build mavenCentral deps with Ant
|
||||
run: ant mavenCentral.deps
|
||||
- name: build Maven dev build with Ant
|
||||
run: ./installer/resources/maven-dev-release.sh 1
|
||||
- name: Upload servlet-i2p.jar
|
||||
|
@ -267,7 +267,7 @@ Applications:
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/LICENSE-ECLIPSE-1.0.html
|
||||
|
||||
RRD4J 3.9 (jrobin.jar):
|
||||
RRD4J 3.9.1 (jrobin.jar):
|
||||
Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
|
||||
Copyright (c) 2011 The OpenNMS Group, Inc.
|
||||
Copyright 2011 The RRD4J Authors.
|
||||
|
@ -997,7 +997,7 @@
|
||||
} // !isRouterContext
|
||||
%>
|
||||
</table>
|
||||
<table class="tunnelConfig" id="customOptions">
|
||||
<table class="tunnelConfig" id="advancedOptions">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<%=intl._t("Custom options")%>
|
||||
|
@ -930,6 +930,7 @@ input.tunnelName, input.tunnelDescriptionText, #userAgents, .freetext.tunnelDesc
|
||||
|
||||
#customOptions {
|
||||
margin-top: 15px !important;
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
#tunnelDepth, #tunnelVariance, #tunnelQuantity, #tunnelBackupQuantity,
|
||||
|
@ -66,7 +66,7 @@
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<jar destfile="./build/jrobin.jar" basedir="./build/obj" includes="**/*.class">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="3.8" />
|
||||
<attribute name="Implementation-Version" value="3.9.1" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
|
@ -310,10 +310,7 @@ public abstract class RrdBackendFactory implements Closeable {
|
||||
}
|
||||
@Override
|
||||
public void clear() {
|
||||
try {
|
||||
backend.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
// backend doesn't need to be closed here as it already happens in RrdBackend.rrdClose()
|
||||
backend = null;
|
||||
super.clear();
|
||||
}
|
||||
|
@ -300,6 +300,9 @@ public class RrdDbPool {
|
||||
RrdEntry ref;
|
||||
try {
|
||||
ref = getEntry(dburi, false);
|
||||
} catch (IllegalStateException e) {
|
||||
// This means that corresponding database has been already closed before, so returning immediately.
|
||||
return;
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IllegalStateException("Release interrupted for " + rrdDb.getPath(), e);
|
||||
|
161
apps/jrobin/java/src/org/rrd4j/graph/BufferedImageWorker.java
Normal file
161
apps/jrobin/java/src/org/rrd4j/graph/BufferedImageWorker.java
Normal file
@ -0,0 +1,161 @@
|
||||
package org.rrd4j.graph;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
class BufferedImageWorker extends ImageWorker {
|
||||
|
||||
static class Builder {
|
||||
private int width = 1;
|
||||
private int height = 1;
|
||||
private RrdGraphDef gdef;
|
||||
private ImageWriter writer;
|
||||
private ImageWriteParam imageWriteParam;
|
||||
BufferedImageWorker build() {
|
||||
return new BufferedImageWorker(this);
|
||||
}
|
||||
private ImageWriteParam getImageParams() {
|
||||
ImageWriteParam iwp = writer.getDefaultWriteParam();
|
||||
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
|
||||
//If lossy compression, use the quality
|
||||
if (! imgProvider.isFormatLossless()) {
|
||||
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
iwp.setCompressionQuality(gdef.imageQuality);
|
||||
}
|
||||
|
||||
if (iwp.canWriteProgressive()) {
|
||||
iwp.setProgressiveMode(gdef.interlaced ? ImageWriteParam.MODE_DEFAULT:ImageWriteParam.MODE_DISABLED);
|
||||
}
|
||||
return iwp;
|
||||
}
|
||||
|
||||
public Builder setWidth(int width) {
|
||||
this.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setHeight(int height) {
|
||||
this.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setGdef(RrdGraphDef gdef) {
|
||||
this.gdef = gdef;
|
||||
if (this.writer == null) {
|
||||
this.writer = ImageIO.getImageWritersByFormatName(gdef.imageFormat).next();
|
||||
}
|
||||
if (this.imageWriteParam == null) {
|
||||
this.imageWriteParam = getImageParams();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setWriter(ImageWriter writer) {
|
||||
this.writer = writer;
|
||||
if (this.imageWriteParam == null) {
|
||||
this.imageWriteParam = getImageParams();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setImageWriteParam(ImageWriteParam imageWriteParam) {
|
||||
this.imageWriteParam = imageWriteParam;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public static Builder getBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
private BufferedImage img;
|
||||
private int imgWidth;
|
||||
private int imgHeight;
|
||||
private AffineTransform initialAffineTransform;
|
||||
private final ImageWriter writer;
|
||||
private final ImageWriteParam iwp;
|
||||
|
||||
private BufferedImageWorker(Builder builder) {
|
||||
this.imgHeight = builder.height;
|
||||
this.imgWidth = builder.width;
|
||||
this.writer = builder.writer;
|
||||
this.iwp = builder.imageWriteParam;
|
||||
resize(imgWidth, imgHeight);
|
||||
}
|
||||
|
||||
/*
|
||||
* Not for use, only for tests
|
||||
*/
|
||||
BufferedImageWorker(int width, int height) {
|
||||
this.imgHeight = height;
|
||||
this.imgWidth = width;
|
||||
this.writer = ImageIO.getImageWritersByFormatName("png").next();
|
||||
this.iwp = writer.getDefaultWriteParam();
|
||||
resize(imgWidth, imgHeight);
|
||||
}
|
||||
|
||||
protected void resize(int width, int height) {
|
||||
imgWidth = width;
|
||||
imgHeight = height;
|
||||
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
setG2d(g2d);
|
||||
initialAffineTransform = g2d.getTransform();
|
||||
|
||||
setAntiAliasing(false);
|
||||
setTextAntiAliasing(false);
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
}
|
||||
|
||||
protected void reset(Graphics2D g2d) {
|
||||
g2d.setTransform(initialAffineTransform);
|
||||
g2d.setClip(0, 0, imgWidth, imgHeight);
|
||||
}
|
||||
|
||||
protected void makeImage(OutputStream stream) throws IOException {
|
||||
BufferedImage outputImage = img;
|
||||
|
||||
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
|
||||
|
||||
img.coerceData(false);
|
||||
|
||||
// Some format can't manage 16M colors images
|
||||
// JPEG don't like transparency
|
||||
if (! imgProvider.canEncodeImage(outputImage) || "image/jpeg".equalsIgnoreCase(imgProvider.getMIMETypes()[0])) {
|
||||
int w = img.getWidth();
|
||||
int h = img.getHeight();
|
||||
outputImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
outputImage.getGraphics().drawImage(img, 0, 0, w, h, null);
|
||||
if (! imgProvider.canEncodeImage(outputImage)) {
|
||||
throw new IllegalArgumentException("Invalid image type");
|
||||
}
|
||||
}
|
||||
|
||||
if (! imgProvider.canEncodeImage(outputImage)) {
|
||||
throw new IllegalArgumentException("Invalid image type");
|
||||
}
|
||||
|
||||
try (ImageOutputStream imageStream = ImageIO.createImageOutputStream(stream)) {
|
||||
writer.setOutput(imageStream);
|
||||
writer.write(null, new IIOImage(outputImage, null, null), iwp);
|
||||
imageStream.flush();
|
||||
} catch (IOException e) {
|
||||
writer.abort();
|
||||
throw e;
|
||||
} finally {
|
||||
writer.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,223 +1,211 @@
|
||||
package org.rrd4j.graph;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Paint;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.*;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
/**
|
||||
* An abstract class, that allows to use custom {@link Graphics2D}. To use it the construct should build it and call
|
||||
* {@link #setG2d(Graphics2D)} when finished.
|
||||
*/
|
||||
public abstract class ImageWorker {
|
||||
|
||||
class ImageWorker {
|
||||
private static final String DUMMY_TEXT = "Dummy";
|
||||
private static final int IMG_BUFFER_CAPACITY = 10000; // bytes
|
||||
|
||||
private BufferedImage img;
|
||||
private Graphics2D g2d;
|
||||
private int imgWidth, imgHeight;
|
||||
private AffineTransform initialAffineTransform;
|
||||
|
||||
ImageWorker(int width, int height) {
|
||||
resize(width, height);
|
||||
}
|
||||
|
||||
void resize(int width, int height) {
|
||||
protected void setG2d(Graphics2D g2d) {
|
||||
if (g2d != null) {
|
||||
dispose();
|
||||
}
|
||||
|
||||
imgWidth = width;
|
||||
imgHeight = height;
|
||||
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
g2d = img.createGraphics();
|
||||
initialAffineTransform = g2d.getTransform();
|
||||
|
||||
setAntiAliasing(false);
|
||||
setTextAntiAliasing(false);
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
this.g2d = g2d;
|
||||
}
|
||||
|
||||
void clip(int x, int y, int width, int height) {
|
||||
protected abstract void resize(int width, int height);
|
||||
|
||||
protected void clip(int x, int y, int width, int height) {
|
||||
g2d.setClip(x, y, width, height);
|
||||
}
|
||||
|
||||
void transform(int x, int y, double angle) {
|
||||
protected void transform(int x, int y, double angle) {
|
||||
g2d.translate(x, y);
|
||||
g2d.rotate(angle);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
g2d.setTransform(initialAffineTransform);
|
||||
g2d.setClip(0, 0, imgWidth, imgHeight);
|
||||
protected void reset() {
|
||||
reset(g2d);
|
||||
}
|
||||
|
||||
void fillRect(int x, int y, int width, int height, Paint paint) {
|
||||
/**
|
||||
* reset the dimensions of the {@link Graphics2D}
|
||||
*/
|
||||
protected abstract void reset(Graphics2D g2d);
|
||||
|
||||
protected void fillRect(int x, int y, int width, int height, Paint paint) {
|
||||
g2d.setPaint(paint);
|
||||
g2d.fillRect(x, y, width, height);
|
||||
}
|
||||
|
||||
void fillPolygon(int[] x, int[] y, Paint paint) {
|
||||
g2d.setPaint(paint);
|
||||
g2d.fillPolygon(x, y, x.length);
|
||||
}
|
||||
|
||||
void fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint) {
|
||||
protected void fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint) {
|
||||
g2d.setPaint(paint);
|
||||
PathIterator path = new PathIterator(yTop);
|
||||
for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
|
||||
int start = pos[0], end = pos[1], n = end - start;
|
||||
int[] xDev = new int[n + 2], yDev = new int[n + 2];
|
||||
int c = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
xDev[i - start] = (int) x[i];
|
||||
yDev[i - start] = (int) yTop[i];
|
||||
int cx = (int) x[i];
|
||||
int cy = (int) yTop[i];
|
||||
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
|
||||
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
|
||||
// collapse horizontal lines
|
||||
xDev[c - 1] = cx;
|
||||
} else {
|
||||
xDev[c] = cx;
|
||||
yDev[c++] = cy;
|
||||
}
|
||||
}
|
||||
}
|
||||
xDev[n] = xDev[n - 1];
|
||||
xDev[n + 1] = xDev[0];
|
||||
yDev[n] = yDev[n + 1] = (int) yBottom;
|
||||
g2d.fillPolygon(xDev, yDev, xDev.length);
|
||||
g2d.drawPolygon(xDev, yDev, xDev.length);
|
||||
xDev[c] = xDev[c - 1];
|
||||
xDev[c + 1] = xDev[0];
|
||||
yDev[c] = yDev[c + 1] = (int) yBottom;
|
||||
g2d.fillPolygon(xDev, yDev, c + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint) {
|
||||
protected void fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint) {
|
||||
g2d.setPaint(paint);
|
||||
PathIterator path = new PathIterator(yTop);
|
||||
for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
|
||||
int start = pos[0], end = pos[1], n = end - start;
|
||||
int[] xDev = new int[n * 2], yDev = new int[n * 2];
|
||||
int c = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
int ix1 = i - start, ix2 = n * 2 - 1 - i + start;
|
||||
xDev[ix1] = xDev[ix2] = (int) x[i];
|
||||
yDev[ix1] = (int) yTop[i];
|
||||
yDev[ix2] = (int) yBottom[i];
|
||||
int cx = (int) x[i];
|
||||
int cy = (int) yTop[i];
|
||||
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
|
||||
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
|
||||
// collapse horizontal lines
|
||||
xDev[c - 1] = cx;
|
||||
} else {
|
||||
xDev[c] = cx;
|
||||
yDev[c++] = cy;
|
||||
}
|
||||
}
|
||||
}
|
||||
g2d.fillPolygon(xDev, yDev, xDev.length);
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
int cx = (int) x[i];
|
||||
int cy = (int) yBottom[i];
|
||||
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
|
||||
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
|
||||
// collapse horizontal lines
|
||||
xDev[c - 1] = cx;
|
||||
} else {
|
||||
xDev[c] = cx;
|
||||
yDev[c++] = cy;
|
||||
}
|
||||
}
|
||||
}
|
||||
g2d.fillPolygon(xDev, yDev, c);
|
||||
}
|
||||
}
|
||||
|
||||
void drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke) {
|
||||
protected void drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke) {
|
||||
g2d.setStroke(stroke);
|
||||
g2d.setPaint(paint);
|
||||
g2d.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void drawPolyline(int[] x, int[] y, Paint paint, Stroke stroke) {
|
||||
g2d.setStroke(stroke);
|
||||
g2d.setPaint(paint);
|
||||
g2d.drawPolyline(x, y, x.length);
|
||||
}
|
||||
|
||||
void drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke) {
|
||||
protected void drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke) {
|
||||
g2d.setPaint(paint);
|
||||
g2d.setStroke(stroke);
|
||||
PathIterator path = new PathIterator(y);
|
||||
for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
|
||||
int start = pos[0], end = pos[1];
|
||||
int[] xDev = new int[end - start], yDev = new int[end - start];
|
||||
int c = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
xDev[i - start] = (int) x[i];
|
||||
yDev[i - start] = (int) y[i];
|
||||
int cx = (int) x[i];
|
||||
int cy = (int) y[i];
|
||||
if (c == 0 || cx != xDev[c - 1] || cy != yDev[c - 1]) {
|
||||
if (c >= 2 && cy == yDev[c - 1] && cy == yDev[c - 2]) {
|
||||
// collapse horizontal lines
|
||||
xDev[c - 1] = cx;
|
||||
} else {
|
||||
xDev[c] = cx;
|
||||
yDev[c++] = cy;
|
||||
}
|
||||
}
|
||||
}
|
||||
g2d.drawPolyline(xDev, yDev, xDev.length);
|
||||
g2d.drawPolyline(xDev, yDev, c);
|
||||
}
|
||||
}
|
||||
|
||||
void drawString(String text, int x, int y, Font font, Paint paint) {
|
||||
protected void drawString(String text, int x, int y, Font font, Paint paint) {
|
||||
g2d.setFont(font);
|
||||
g2d.setPaint(paint);
|
||||
g2d.drawString(text, x, y);
|
||||
}
|
||||
|
||||
double getFontAscent(Font font) {
|
||||
protected double getFontAscent(Font font) {
|
||||
LineMetrics lm = font.getLineMetrics(DUMMY_TEXT, g2d.getFontRenderContext());
|
||||
return lm.getAscent();
|
||||
}
|
||||
|
||||
double getFontHeight(Font font) {
|
||||
protected double getFontHeight(Font font) {
|
||||
LineMetrics lm = font.getLineMetrics(DUMMY_TEXT, g2d.getFontRenderContext());
|
||||
return lm.getAscent() + lm.getDescent();
|
||||
}
|
||||
|
||||
double getStringWidth(String text, Font font) {
|
||||
protected double getStringWidth(String text, Font font) {
|
||||
return font.getStringBounds(text, 0, text.length(), g2d.getFontRenderContext()).getBounds().getWidth();
|
||||
}
|
||||
|
||||
void setAntiAliasing(boolean enable) {
|
||||
protected void setAntiAliasing(boolean enable) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
enable ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||
}
|
||||
|
||||
void setTextAntiAliasing(boolean enable) {
|
||||
protected void setTextAntiAliasing(boolean enable) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
enable ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
void makeImage(Object stream, ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
BufferedImage outputImage = img;
|
||||
|
||||
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
|
||||
|
||||
img.coerceData(false);
|
||||
|
||||
// Some format can't manage 16M colors images
|
||||
// JPEG don't like transparency
|
||||
if (! imgProvider.canEncodeImage(outputImage) || "image/jpeg".equalsIgnoreCase(imgProvider.getMIMETypes()[0])) {
|
||||
int w = img.getWidth();
|
||||
int h = img.getHeight();
|
||||
outputImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
outputImage.getGraphics().drawImage(img, 0, 0, w, h, null);
|
||||
if (! imgProvider.canEncodeImage(outputImage)) {
|
||||
throw new RuntimeException("Invalid image type");
|
||||
}
|
||||
}
|
||||
|
||||
if (! imgProvider.canEncodeImage(outputImage)) {
|
||||
throw new RuntimeException("Invalid image type");
|
||||
}
|
||||
|
||||
try (ImageOutputStream imageStream = ImageIO.createImageOutputStream(stream)) {
|
||||
writer.setOutput(imageStream);
|
||||
writer.write(null, new IIOImage(outputImage, null, null), iwp);
|
||||
imageStream.flush();
|
||||
} catch (IOException e) {
|
||||
writer.abort();
|
||||
throw e;
|
||||
} finally {
|
||||
writer.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void saveImage(String path, ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
makeImage(Paths.get(path).toFile(), writer, iwp);
|
||||
}
|
||||
|
||||
byte[] getImageBytes(ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(IMG_BUFFER_CAPACITY)){
|
||||
makeImage(stream, writer, iwp);
|
||||
return stream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
void loadImage(RrdGraphDef.ImageSource imageSource, int x, int y, int w, int h) throws IOException {
|
||||
protected void loadImage(RrdGraphDef.ImageSource imageSource, int x, int y, int w, int h) throws IOException {
|
||||
BufferedImage wpImage = imageSource.apply(w, h).getSubimage(0, 0, w, h);
|
||||
g2d.drawImage(wpImage, new AffineTransform(1f, 0f, 0f, 1f, x, y), null);
|
||||
}
|
||||
|
||||
protected void dispose() {
|
||||
if (g2d != null) {
|
||||
g2d.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected void makeImage(Path path) throws IOException {
|
||||
try (OutputStream os = Files.newOutputStream(path)) {
|
||||
makeImage(os);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void makeImage(OutputStream os) throws IOException ;
|
||||
|
||||
protected void saveImage(String path) throws IOException {
|
||||
makeImage(Paths.get(path));
|
||||
}
|
||||
|
||||
protected byte[] getImageBytes() throws IOException {
|
||||
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(IMG_BUFFER_CAPACITY)){
|
||||
makeImage(stream);
|
||||
return stream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,10 +12,8 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.rrd4j.core.Util;
|
||||
@ -38,7 +36,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
};
|
||||
|
||||
private static final int SYMBOLS_CENTER = 8;
|
||||
private static final char[] SYMBOLS = {'y', 'z', 'a', 'f', 'p', 'n', 'µ', 'm', ' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
|
||||
private static final char[] SYMBOLS = {'y', 'z', 'a', 'f', 'p', 'n', 'µ', 'm', ' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
|
||||
|
||||
final RrdGraphDef gdef;
|
||||
final ImageParameters im;
|
||||
@ -47,8 +45,6 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
Mapper mapper;
|
||||
private final RrdGraphInfo info = new RrdGraphInfo();
|
||||
private final String signature;
|
||||
private final ImageWriter writer;
|
||||
private final ImageWriteParam param;
|
||||
|
||||
/**
|
||||
* Creates graph from the corresponding {@link org.rrd4j.graph.RrdGraphDef} object.
|
||||
@ -60,9 +56,8 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
this.gdef = gdef;
|
||||
signature = gdef.getSignature();
|
||||
im = new ImageParameters();
|
||||
worker = new ImageWorker(1, 1); // Dummy worker, just to start with something
|
||||
writer = ImageIO.getImageWritersByFormatName(gdef.imageFormat).next();
|
||||
param = getImageParams();
|
||||
|
||||
worker = BufferedImageWorker.getBuilder().setGdef(gdef).build();
|
||||
try {
|
||||
createGraph();
|
||||
}
|
||||
@ -73,6 +68,28 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create graph from a custom image worker
|
||||
* @param gdef
|
||||
* @param worker
|
||||
* @throws IOException
|
||||
*/
|
||||
public RrdGraph(RrdGraphDef gdef, ImageWorker worker) throws IOException {
|
||||
this.gdef = gdef;
|
||||
signature = gdef.getSignature();
|
||||
im = new ImageParameters();
|
||||
this.worker = worker;
|
||||
try {
|
||||
createGraph();
|
||||
}
|
||||
finally {
|
||||
worker.dispose();
|
||||
this.worker = null;
|
||||
dproc = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Creates graph from the corresponding {@link org.rrd4j.graph.RrdGraphDef} object.</p>
|
||||
* <p>The graph will be created using customs {@link javax.imageio.ImageWriter} and {@link javax.imageio.ImageWriteParam} given.</p>
|
||||
@ -88,9 +105,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
this.gdef = gdef;
|
||||
signature = gdef.getSignature();
|
||||
im = new ImageParameters();
|
||||
worker = new ImageWorker(1, 1); // Dummy worker, just to start with something
|
||||
this.writer = writer;
|
||||
this.param = param;
|
||||
worker = BufferedImageWorker.getBuilder().setGdef(gdef).setWriter(writer).setImageWriteParam(param).build();
|
||||
try {
|
||||
createGraph();
|
||||
}
|
||||
@ -110,21 +125,6 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
return info;
|
||||
}
|
||||
|
||||
private ImageWriteParam getImageParams() {
|
||||
ImageWriteParam iwp = writer.getDefaultWriteParam();
|
||||
ImageWriterSpi imgProvider = writer.getOriginatingProvider();
|
||||
//If lossy compression, use the quality
|
||||
if (! imgProvider.isFormatLossless()) {
|
||||
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
iwp.setCompressionQuality(gdef.imageQuality);
|
||||
}
|
||||
|
||||
if (iwp.canWriteProgressive()) {
|
||||
iwp.setProgressiveMode(gdef.interlaced ? ImageWriteParam.MODE_DEFAULT:ImageWriteParam.MODE_DISABLED);
|
||||
}
|
||||
return iwp;
|
||||
}
|
||||
|
||||
private void createGraph() throws IOException {
|
||||
boolean lazy = lazyCheck();
|
||||
if (!lazy || gdef.printStatementCount() != 0) {
|
||||
@ -177,7 +177,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
private void saveImage() throws IOException {
|
||||
if (! RrdGraphConstants.IN_MEMORY_IMAGE.equals(gdef.filename)) {
|
||||
Path imgpath = Paths.get(gdef.filename);
|
||||
worker.saveImage(gdef.filename, writer, param);
|
||||
worker.saveImage(gdef.filename);
|
||||
info.bytesSource = () -> {
|
||||
try {
|
||||
return Files.readAllBytes(imgpath);
|
||||
@ -194,7 +194,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
};
|
||||
}
|
||||
else {
|
||||
byte[] content = worker.getImageBytes(writer, param);
|
||||
byte[] content = worker.getImageBytes();
|
||||
info.bytesSource = () -> Arrays.copyOf(content, content.length);
|
||||
info.bytesCount = () -> content.length;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package org.rrd4j.graph;
|
||||
class ValueScaler {
|
||||
static final String UNIT_UNKNOWN = "?";
|
||||
static final String[] UNIT_SYMBOLS = {
|
||||
"a", "f", "p", "n", "u", "m", " ", "k", "M", "G", "T", "P", "E"
|
||||
"a", "f", "p", "n", "µ", "m", " ", "K", "M", "G", "T", "P", "E"
|
||||
};
|
||||
static final int SYMB_CENTER = 6;
|
||||
|
||||
|
@ -83,6 +83,8 @@ class SummaryRenderer {
|
||||
private static final long[] RATES = new long[] { 60*60*1000 };
|
||||
// dotted line
|
||||
private static final Stroke GRID_STROKE = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[] {1, 1}, 0);
|
||||
// hide grid
|
||||
private static final Stroke TICK_STROKE = new BasicStroke(0);
|
||||
|
||||
public SummaryRenderer(I2PAppContext ctx, SummaryListener lsnr) {
|
||||
_log = ctx.logManager().getLog(SummaryRenderer.class);
|
||||
@ -337,6 +339,7 @@ class SummaryRenderer {
|
||||
def.setAntiAliasing(false);
|
||||
def.setTextAntiAliasing(true);
|
||||
def.setGridStroke(GRID_STROKE);
|
||||
def.setTickStroke(TICK_STROKE);
|
||||
//System.out.println("Rendering: \n" + def.exportXmlTemplate());
|
||||
//System.out.println("*****************\nData: \n" + _listener.getData().dump());
|
||||
def.setWidth(width);
|
||||
|
@ -31,7 +31,7 @@ public class CoreVersion {
|
||||
* Otherwise, the same as PUBLISHED_VERSION.
|
||||
* RouterVersion.FULL_VERSION is suggested for display to the user.
|
||||
*/
|
||||
public final static String VERSION = "2.5.0";
|
||||
public final static String VERSION = "2.5.1";
|
||||
|
||||
/**
|
||||
* The version published in the netdb via StatisticsManager.
|
||||
|
@ -1,3 +1,9 @@
|
||||
i2p (2.5.1-1~bionic+1) bionic; urgency=medium
|
||||
|
||||
* New upstream version 2.5.1
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Tue, 07 May 2024 11:18:05 -0400
|
||||
|
||||
i2p (2.5.0-1~bionic+1) bionic; urgency=medium
|
||||
|
||||
* New upstream version 2.5.0
|
||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
||||
i2p (2.5.1-1~ubuntu1) focal; urgency=medium
|
||||
|
||||
* New upstream version 2.5.1
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Tue, 07 May 2024 11:17:09 -0400
|
||||
|
||||
i2p (2.5.0-1~ubuntu1) focal; urgency=medium
|
||||
|
||||
* New upstream version 2.5.0
|
||||
|
12
history.txt
12
history.txt
@ -1,3 +1,13 @@
|
||||
2024-05-12 zzz
|
||||
* Console: Update rrd4j to 3.9.1 preview
|
||||
|
||||
2024-05-08 zzz
|
||||
* i2ptunnel: Fix custom options form width (light theme)
|
||||
* Router: Publish G cap if symmetric natted
|
||||
* Tunnels: Validate peer RI expiration in TunnelPeerSelector
|
||||
|
||||
2024-05-06 2.5.1 (API 0.9.62) released
|
||||
|
||||
2024-05-05 zzz
|
||||
* NetDB: Various fixes and adjustments
|
||||
* Pull translations from Transifex
|
||||
@ -8,7 +18,7 @@
|
||||
* Tunnels: OBEP distributor: Check and charge RI lookup bandwidth
|
||||
|
||||
2024-05-02 zzz
|
||||
* Profiles: Fixes for firstHeardAbout and/or lastHeardAbout being zero
|
||||
* Profiles: Fixes for firstHeardAbout and/or lastHeardAbout being zero
|
||||
|
||||
2024-05-01 zzz
|
||||
* NetDB:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<info>
|
||||
<appname>i2p</appname>
|
||||
<appversion>2.5.0</appversion>
|
||||
<appversion>2.5.1</appversion>
|
||||
<authors>
|
||||
<author name="I2P" email="https://geti2p.net/"/>
|
||||
</authors>
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<info>
|
||||
<appname>i2p</appname>
|
||||
<appversion>2.5.0</appversion>
|
||||
<appversion>2.5.1</appversion>
|
||||
<authors>
|
||||
<author name="I2P" email="https://geti2p.net/"/>
|
||||
</authors>
|
||||
|
@ -196,7 +196,7 @@
|
||||
2. Add i2pupdate-1.xx.0.su3 torrent to tracker2.postman.i2p and start seeding
|
||||
|
||||
3. Notify the following people:
|
||||
- All in-network update hosts
|
||||
- All in-network update hosts(zzz(stats.i2p) and idk(mgp**.b32.i2p)), they will need the i2pupdate.su3 file
|
||||
- PPA maintainer
|
||||
- news.xml maintainer
|
||||
- backup news.xml maintainer
|
||||
|
@ -1203,6 +1203,7 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
// rv.append(CAPABILITY_NO_TUNNELS);
|
||||
return rv.toString();
|
||||
}
|
||||
boolean forceG = false;
|
||||
switch (_context.commSystem().getStatus()) {
|
||||
case OK:
|
||||
case IPV4_OK_IPV6_UNKNOWN:
|
||||
@ -1215,18 +1216,21 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
break;
|
||||
|
||||
case DIFFERENT:
|
||||
case HOSED:
|
||||
case IPV4_SNAT_IPV6_UNKNOWN:
|
||||
forceG = true;
|
||||
// fall through
|
||||
|
||||
case REJECT_UNSOLICITED:
|
||||
case IPV4_DISABLED_IPV6_FIREWALLED:
|
||||
rv.append(CAPABILITY_UNREACHABLE);
|
||||
break;
|
||||
|
||||
case DISCONNECTED:
|
||||
case HOSED:
|
||||
case UNKNOWN:
|
||||
case IPV4_UNKNOWN_IPV6_FIREWALLED:
|
||||
case IPV4_DISABLED_IPV6_UNKNOWN:
|
||||
case IPV4_FIREWALLED_IPV6_UNKNOWN:
|
||||
case IPV4_SNAT_IPV6_UNKNOWN:
|
||||
default:
|
||||
// no explicit capability
|
||||
break;
|
||||
@ -1234,7 +1238,7 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
|
||||
char cong = 0;
|
||||
int maxTunnels = _context.getProperty(RouterThrottleImpl.PROP_MAX_TUNNELS, RouterThrottleImpl.DEFAULT_MAX_TUNNELS);
|
||||
if (maxTunnels <= 0) {
|
||||
if (forceG || maxTunnels <= 0) {
|
||||
cong = CAPABILITY_NO_TUNNELS;
|
||||
} else if (maxTunnels <= 50 || SystemVersion.isSlow()) {
|
||||
cong = CAPABILITY_CONGESTION_MODERATE;
|
||||
|
@ -20,7 +20,7 @@ public class RouterVersion {
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
/** for example: "beta", "alpha", "rc" */
|
||||
public final static String QUALIFIER = "";
|
||||
public final static long BUILD = 4;
|
||||
public final static long BUILD = 1;
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
public final static String FULL_VERSION = VERSION + "-" + BUILD + QUALIFIER + EXTRA;
|
||||
|
@ -229,7 +229,10 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
||||
if (ctx.commSystem().wasUnreachable(h))
|
||||
return true;
|
||||
|
||||
RouterInfo info = (RouterInfo) ctx.netDb().lookupLocallyWithoutValidation(h);
|
||||
// Here, we use validation, because BuildRequestor does,
|
||||
// so if we don't skip old routers here, it gets all the way to BuildRequestor
|
||||
// before failing.
|
||||
RouterInfo info = (RouterInfo) ctx.netDb().lookupLocally(h);
|
||||
if (info == null)
|
||||
return true;
|
||||
|
||||
|
Reference in New Issue
Block a user