Skip to content

Commit 460e6f9

Browse files
committed
Add WEBP support, via cwebp/dwebp tools
1 parent f1c0cfa commit 460e6f9

File tree

5 files changed

+170
-184
lines changed

5 files changed

+170
-184
lines changed

DynmapCore/src/main/java/org/dynmap/DynmapCore.java

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.zip.ZipEntry;
3434
import java.util.zip.ZipFile;
3535

36+
import org.dynmap.MapType.ImageEncoding;
3637
import org.dynmap.common.DynmapCommandSender;
3738
import org.dynmap.common.DynmapListenerManager;
3839
import org.dynmap.common.DynmapListenerManager.EventType;
@@ -138,6 +139,12 @@ public static abstract class EnableCoreCallbacks {
138139

139140
private boolean loginRequired;
140141

142+
// WEBP support
143+
private String cwebpPath;
144+
private String dwebpPath;
145+
private boolean did_cwebpPath_warn = false;
146+
private boolean did_dwebpPath_warn = false;
147+
141148
/* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */
142149
public boolean is_reload = false;
143150
public static boolean ignore_chunk_loads = false; /* Flag keep us from processing our own chunk loads */
@@ -200,7 +207,6 @@ public final File getExportFolder() {
200207
public void setMinecraftVersion(String mcver) {
201208
this.platformVersion = mcver;
202209
}
203-
204210
public void setServer(DynmapServerInterface srv) {
205211
server = srv;
206212
}
@@ -213,6 +219,21 @@ public final void setBiomeNames(String[] names) {
213219
public static final boolean migrateChunks() {
214220
return migrate_chunks;
215221
}
222+
223+
public String getCWEBPPath() {
224+
if ((cwebpPath == null) && (!did_cwebpPath_warn)) {
225+
Log.severe("ERROR: trying to use WEBP without cwebp tool installed or cwebpPath set properly");
226+
did_cwebpPath_warn = true;
227+
}
228+
return cwebpPath;
229+
}
230+
public String getDWEBPPath() {
231+
if ((dwebpPath == null) && (!did_dwebpPath_warn)) {
232+
Log.severe("ERROR: trying to use WEBP without dwebp tool installed or dwebpPath set properly");
233+
did_dwebpPath_warn = true;
234+
}
235+
return dwebpPath;
236+
}
216237

217238
public final String getBiomeName(int biomeid) {
218239
String n = null;
@@ -416,6 +437,20 @@ else if (storetype.equals("postgres") || storetype.equals("postgresql")) {
416437
return true;
417438
}
418439

440+
private String findExecutableOnPath(String fname) {
441+
for (String dirname : System.getenv("PATH").split(File.pathSeparator)) {
442+
File file = new File(dirname, fname);
443+
if (file.isFile() && file.canExecute()) {
444+
return file.getAbsolutePath();
445+
}
446+
file = new File(dirname, fname + ".exe");
447+
if (file.isFile() && file.canExecute()) {
448+
return file.getAbsolutePath();
449+
}
450+
}
451+
return null;
452+
}
453+
419454
public boolean enableCore(EnableCoreCallbacks cb) {
420455
/* Update extracted files, if needed */
421456
updateExtractedFiles();
@@ -427,14 +462,47 @@ public boolean enableCore(EnableCoreCallbacks cb) {
427462

428463
/* Load control for leaf transparency (spout lighting bug workaround) */
429464
transparentLeaves = configuration.getBoolean("transparent-leaves", true);
465+
466+
// Inject core instance
467+
ImageIOManager.core = this;
468+
// Check for webp support
469+
cwebpPath = configuration.getString("cwebpPath", null);
470+
dwebpPath = configuration.getString("dwebpPath", null);
471+
if (cwebpPath == null) {
472+
cwebpPath = findExecutableOnPath("cwebp");
473+
}
474+
if (dwebpPath == null) {
475+
dwebpPath = findExecutableOnPath("dwebp");
476+
}
477+
if (cwebpPath != null) {
478+
File file = new File(cwebpPath);
479+
if (!file.isFile() || !file.canExecute()) {
480+
cwebpPath = null;
481+
}
482+
}
483+
if (dwebpPath != null) {
484+
File file = new File(dwebpPath);
485+
if (!file.isFile() || !file.canExecute()) {
486+
dwebpPath = null;
487+
}
488+
}
489+
if ((cwebpPath != null) && (dwebpPath != null)) {
490+
Log.info("Found cwebp at " + cwebpPath + " and dwebp at " + dwebpPath + ": webp format enabled");
491+
}
492+
else {
493+
Log.warning("cwebp or dwebp not found, or cwebpPath or dwebpPath is invalid: webp format disabled");
494+
cwebpPath = dwebpPath = null;
495+
}
430496
/* Get default image format */
431497
def_image_format = configuration.getString("image-format", "png");
432498
MapType.ImageFormat fmt = MapType.ImageFormat.fromID(def_image_format);
433-
if(fmt == null) {
499+
if ((fmt == null) || ((fmt.enc == ImageEncoding.WEBP) && (cwebpPath == null))) {
434500
Log.severe("Invalid image-format: " + def_image_format);
435501
def_image_format = "png";
502+
fmt = MapType.ImageFormat.fromID(def_image_format);
436503
}
437504

505+
438506
DynmapWorld.doInitialScan(configuration.getBoolean("initial-zoomout-validate", true));
439507

440508
smoothlighting = configuration.getBoolean("smooth-lighting", false);

DynmapCore/src/main/java/org/dynmap/DynmapWorld.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private void processZoomFile(MapTypeState mts, MapStorageTile tile, boolean firs
157157
if (tr != null) {
158158
BufferedImage im = null;
159159
try {
160-
im = ImageIOManager.imageIODecode(tr.image);
160+
im = ImageIOManager.imageIODecode(tr);
161161
} catch (IOException iox) {
162162
// Broken file - zap it
163163
tile1.delete();

DynmapCore/src/main/java/org/dynmap/MapType.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@ public enum ImageVariant {
3030
}
3131

3232
public enum ImageEncoding {
33-
PNG("png"), JPG("jpg");
33+
PNG("png", "image/png"), JPG("jpg", "image/jpeg"), WEBP("webp", "image/webp");
3434
public final String ext;
35+
public final String mimetype;
3536

36-
ImageEncoding(String ext) {
37+
ImageEncoding(String ext, String mime) {
3738
this.ext = ext;
39+
this.mimetype = mime;
3840
}
3941
public String getFileExt() { return ext; }
42+
public String getContentType() { return mimetype; }
4043

4144
public static ImageEncoding fromOrd(int ix) {
4245
ImageEncoding[] v = values();
@@ -63,7 +66,14 @@ public enum ImageFormat {
6366
FORMAT_JPG("jpg", 0.85f, ImageEncoding.JPG),
6467
FORMAT_JPG90("jpg-q90", 0.90f, ImageEncoding.JPG),
6568
FORMAT_JPG95("jpg-q95", 0.95f, ImageEncoding.JPG),
66-
FORMAT_JPG100("jpg-q100", 1.00f, ImageEncoding.JPG);
69+
FORMAT_JPG100("jpg-q100", 1.00f, ImageEncoding.JPG),
70+
FORMAT_WEBP75("webp-q75", 75, ImageEncoding.WEBP),
71+
FORMAT_WEBP80("webp-q80", 80, ImageEncoding.WEBP),
72+
FORMAT_WEBP85("webp-q85", 85, ImageEncoding.WEBP),
73+
FORMAT_WEBP("webp", 85, ImageEncoding.WEBP),
74+
FORMAT_WEBP90("webp-q90", 90, ImageEncoding.WEBP),
75+
FORMAT_WEBP95("webp-q95", 95, ImageEncoding.WEBP),
76+
FORMAT_WEBP100("webp-q100", 100, ImageEncoding.WEBP);
6777
String id;
6878
float qual;
6979
ImageEncoding enc;

DynmapCore/src/main/java/org/dynmap/servlet/MapStorageResourceHandler.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques
120120
// Got tile, package up for response
121121
response.setDateHeader("Last-Modified", tr.lastModified);
122122
response.setIntHeader("Content-Length", tr.image.length());
123-
if (tr.format == ImageEncoding.PNG) {
124-
response.setContentType("image/png");
125-
}
126-
else {
127-
response.setContentType("image/jpeg");
128-
}
123+
response.setContentType(tr.format.getContentType());
129124
ServletOutputStream out = response.getOutputStream();
130125
out.write(tr.image.buffer(), 0, tr.image.length());
131126
out.flush();

0 commit comments

Comments
 (0)