gephi/trunk — Issue #68: SeadragonExporter crashes when run through Toolkit
Author: mbastian
Created: 2011-10-22 16:42:10+00:00
State: open
Labels: Fix Committed, High, seadragon, tilerenderer

I am using the Toolkit to try to export via the SeadragonExporter. I extracted the org-gephi-plugins-seadragon.jar and imgscalr-lib-3.1.jar from the seadragon NPM.

My code looks like this:

SeadragonExporter exporter = new SeadragonExporter();

exporter.setPath(new File("/tmp/test"));

Workspace currentWorkspace = Lookup.getDefault().lookup(ProjectController.class).getCurrentWorkspace();
exporter.setWorkspace(currentWorkspace);

exporter.setTileSize(256);
exporter.setWidth(8000);
exporter.setHeight(8000);
exporter.setMargin(20);
exporter.execute();

which throws this error:

Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at org.gephi.plugins.seadragon.SeadragonExporter.execute(SeadragonExporter.java:96)
at org.gephi.toolkit.demos.HeadlessSimple.script(HeadlessSimple.java:180)
at org.gephi.toolkit.demos.Main.main(Main.java:41)
Caused by: java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:999)
at java.awt.image.BufferedImage.(BufferedImage.java:324)
at com.thebuzzmedia.imgscalr.Scalr.scaleImage(Scalr.java:1785)
at com.thebuzzmedia.imgscalr.Scalr.scaleImageIncrementally(Scalr.java:1868)
at com.thebuzzmedia.imgscalr.Scalr.resize(Scalr.java:1502)
at com.thebuzzmedia.imgscalr.Scalr.resize(Scalr.java:1022)
at org.gephi.plugins.seadragon.TileRenderer.writeLevel(TileRenderer.java:40)
at org.gephi.plugins.seadragon.SeadragonExporter.export(SeadragonExporter.java:134)
at org.gephi.plugins.seadragon.SeadragonExporter.execute(SeadragonExporter.java:94)
... 2 more

I ran it through the debugger and it looks like what's happening is SeadragonExporter.export loops through all the levels, in my case, 12 levels, calculating a levelScale for each and sending this to TileRenderer.writeLevel

writeLevel then creates an image with this code:

BufferedImage scaledImage = Scalr.resize(image, Scalr.Method.QUALITY, (int) (scale * image.getWidth()), (int) (scale * image.getHeight()), Scalr.OP_ANTIALIAS);

But as you can see, when we get down to the final level, 0:

main[1] print level
level = 3
main[1] print levelScale
levelScale = 0.001953125
main[1] cont
>
Breakpoint hit: "thread=main", org.gephi.plugins.seadragon.SeadragonExporter.export(), line=134 bci=261

main[1] print level
level = 2
main[1] print levelScale
levelScale = 9.765625E-4
main[1] cont
>
Breakpoint hit: "thread=main", org.gephi.plugins.seadragon.SeadragonExporter.export(), line=134 bci=261

main[1] print level
level = 1
main[1] print levelScale
levelScale = 4.8828125E-4
main[1] cont
>
Breakpoint hit: "thread=main", org.gephi.plugins.seadragon.SeadragonExporter.export(), line=134 bci=261

main[1] print level
level = 0
main[1] print levelScale
levelScale = 2.4414062E-4

The levelScale is so small that levelScale * image.getWidth() approximates to 0, which throws the exception because we can't create an image with a width or a height of 0. I've tried running deepZoom on my exported image normally and it looks like at the 0 level it is a 1x1 pixel image anyway.

Can we patch the code to return 1 instead of 0 for the calculation if it calculates to 0?