diff --git a/src/main/java/bdv/BigDataViewer.java b/src/main/java/bdv/BigDataViewer.java index 9f2390ba1f9e6d395970af9e094bbf07c15180f2..88583bc6fb0e130ccce577f2521562b4a9bceeac 100644 --- a/src/main/java/bdv/BigDataViewer.java +++ b/src/main/java/bdv/BigDataViewer.java @@ -243,7 +243,7 @@ public class BigDataViewer { final ViewerImgLoader imgLoader = (ViewerImgLoader) spimData.getSequenceDescription().getImgLoader(); @SuppressWarnings("unchecked") final ViewerSetupImgLoader<T, V> setupImgLoader = (ViewerSetupImgLoader<T, V>) imgLoader.getSetupImgLoader( - setupId); + setupId); final T type = setupImgLoader.getImageType(); final V volatileType = setupImgLoader.getVolatileImageType(); @@ -636,38 +636,19 @@ public class BigDataViewer { } public static void main(final String[] args) { - // final String fn = "http://tomancak-mac-17.mpi-cbg.de:8080/openspim/"; - // final String fn = "/Users/Pietzsch/Desktop/openspim/datasetHDF.xml"; - // final String fn = "/Users/pietzsch/workspace/data/111010_weber_full.xml"; - // final String fn = "/Users/Pietzsch/Desktop/spimrec2/dataset.xml"; - // final String fn = "/Users/pietzsch/Desktop/HisYFP-SPIM/dataset.xml"; - // final String fn = "/Users/Pietzsch/Desktop/bdv example/drosophila 2.xml"; - // final String fn = "/Users/pietzsch/Desktop/data/clusterValia/140219-1/valia-140219-1.xml"; - // final String fn = "/Users/Pietzsch/Desktop/data/catmaid.xml"; - // final String fn = "src/main/resources/openconnectome-bock11-neariso.xml"; - // final String fn = "/home/saalfeld/catmaid.xml"; - // final String fn = "/home/saalfeld/catmaid-fafb00-v9.xml"; - // final String fn = "/home/saalfeld/catmaid-fafb00-sample_A_cutout_3k.xml"; - // final String fn = "/home/saalfeld/catmaid-thorsten.xml"; - // final String fn = "/home/saalfeld/knossos-example.xml"; - // final String fn = "/Users/Pietzsch/Desktop/data/catmaid-confocal.xml"; - // final String fn = "/Users/pietzsch/desktop/data/BDV130418A325/BDV130418A325_NoTempReg.xml"; - // final String fn = "/Users/pietzsch/Desktop/data/valia2/valia.xml"; - // final String fn = "/Users/pietzsch/workspace/data/fast fly/111010_weber/combined.xml"; - // final String fn = "/Users/pietzsch/workspace/data/mette/mette.xml"; - // final String fn = "/Users/tobias/Desktop/openspim.xml"; - // final String fn = "/Users/pietzsch/Desktop/data/fibsem.xml"; - // final String fn = "/Users/pietzsch/Desktop/data/fibsem-remote.xml"; - // final String fn = "/Users/pietzsch/Desktop/url-valia.xml"; - // final String fn = "/Users/pietzsch/Desktop/data/clusterValia/140219-1/valia-140219-1.xml"; - // final String fn = "/Users/pietzsch/workspace/data/111010_weber_full.xml"; - // final String fn = "/Volumes/projects/tomancak_lightsheet/Mette/ZeissZ1SPIM/Maritigrella/021013_McH2BsGFP_CAAX-mCherry/11-use/hdf5/021013_McH2BsGFP_CAAX-mCherry-11-use.xml"; + + // Default + String fn = "http://127.0.0.1:8080/drosophila32"; + + if (args.length < 1) { System.err.println("Provide path."); return; } - final String fn = args[0]; + + fn = args[0]; final boolean allowCompression = (args.length > 1) && (args[1].equals("-qcmp")); + try { System.setProperty("apple.laf.useScreenMenuBar", "true"); @@ -677,7 +658,6 @@ public class BigDataViewer { ViewerOptions.options(), allowCompression); - // DumpInputConfig.writeToYaml( System.getProperty( "user.home" ) + "/.bdv/bdvkeyconfig.yaml", bdv.getViewerFrame() ); } catch (final Exception e) { e.printStackTrace(); } diff --git a/src/main/java/bdv/img/remote/RemoteImageLoader.java b/src/main/java/bdv/img/remote/RemoteImageLoader.java index 2d5247a2995966d20952922aeada3d75252c9188..839771a63baba5790423be74050370c78a5e0c5d 100644 --- a/src/main/java/bdv/img/remote/RemoteImageLoader.java +++ b/src/main/java/bdv/img/remote/RemoteImageLoader.java @@ -31,6 +31,7 @@ package bdv.img.remote; import azgracompress.cache.ICacheFile; import azgracompress.cache.QuantizationCacheManager; +import azgracompress.compression.ImageDecompressor; import bdv.AbstractViewerSetupImgLoader; import bdv.ViewerImgLoader; import bdv.img.cache.VolatileCachedCellImg; @@ -55,6 +56,7 @@ import net.imglib2.view.Views; import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; @@ -69,7 +71,12 @@ public class RemoteImageLoader implements ViewerImgLoader { protected RemoteVolatileShortArrayLoader shortLoader; + /** + * Flag whether we allow the server to send us compressed data. + */ private boolean allowCompression; + + /** * TODO */ @@ -102,10 +109,6 @@ public class RemoteImageLoader implements ViewerImgLoader { return; isOpen = true; - if (allowCompression) { - receiveCompressionInfo(); - } - final URL url = new URL(baseUrl + "?p=init"); final GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(AffineTransform3D.class, new AffineTransform3DJsonSerializer()); @@ -117,6 +120,10 @@ public class RemoteImageLoader implements ViewerImgLoader { cellsDimensions = metadata.createCellsDimensions(); for (final int setupId : metadata.perSetupMipmapInfo.keySet()) setupImgLoaders.put(setupId, new SetupImgLoader(setupId)); + + if (allowCompression) { + setupCompression(); + } } } } @@ -129,10 +136,20 @@ public class RemoteImageLoader implements ViewerImgLoader { this.allowCompression = compressionEnabled; } - private void receiveCompressionInfo() throws IOException { + private void setupCompression() throws IOException { final URL url = new URL(baseUrl + "?p=init_qcmp"); - final ICacheFile cachedCodebook = QuantizationCacheManager.readCacheFile(url.openStream()); - System.out.println("\u001b[33mRemoteImageLoader::receiveCompressionInfo() - received cache file. '" + cachedCodebook.toString() + "'\u001b[0m"); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + System.out.println("\u001b[33mRemoteImageLoader::setupCompression() - Server doesn't provide compressed data.\u001b[0m"); + return; + } + final ICacheFile cachedCodebook = QuantizationCacheManager.readCacheFile(connection.getInputStream()); + System.out.println("\u001b[33mRemoteImageLoader::setupCompression() - received cache file. '" + cachedCodebook + "'\u001b[0m"); + shortLoader.setDataDecompressor(new ImageDecompressor(cachedCodebook)); + System.out.println("\u001b[33mRemoteImageLoader::setupCompression() - instantiated image decompressor in shortLoader.\u001b[0m"); } diff --git a/src/main/java/bdv/img/remote/RemoteVolatileShortArrayLoader.java b/src/main/java/bdv/img/remote/RemoteVolatileShortArrayLoader.java index ea2582129362c2f21434d88805fc8e97b6539167..600780828a5b4d6ae6d1696ed370f0ffb0bde510 100644 --- a/src/main/java/bdv/img/remote/RemoteVolatileShortArrayLoader.java +++ b/src/main/java/bdv/img/remote/RemoteVolatileShortArrayLoader.java @@ -31,67 +31,117 @@ package bdv.img.remote; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import azgracompress.compression.ImageDecompressor; import bdv.img.cache.CacheArrayLoader; import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray; -public class RemoteVolatileShortArrayLoader implements CacheArrayLoader< VolatileShortArray > -{ - private final RemoteImageLoader imgLoader; - - public RemoteVolatileShortArrayLoader( final RemoteImageLoader imgLoader ) - { - this.imgLoader = imgLoader; - } - - @Override - public VolatileShortArray loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException - { - final int index = imgLoader.getCellIndex( timepoint, setup, level, min ); - final short[] data = new short[ dimensions[ 0 ] * dimensions[ 1 ] * dimensions[ 2 ] ]; - try - { - final URL url = new URL(String.format("%s?p=cell/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d", - imgLoader.baseUrl, - index, - timepoint, - setup, - level, - dimensions[0], - dimensions[1], - dimensions[2], - min[0], - min[1], - min[2])); - final InputStream s = url.openStream(); -// System.out.println("Request URL=" + url); +public class RemoteVolatileShortArrayLoader implements CacheArrayLoader<VolatileShortArray> { + private final RemoteImageLoader imgLoader; + + private ImageDecompressor decompressor; + private boolean requestCompressedData = false; + + public RemoteVolatileShortArrayLoader(final RemoteImageLoader imgLoader) { + this.imgLoader = imgLoader; + } + + private String constructRequestUrl(final String baseParam, + final int timepoint, + final int setup, + final int level, + final int[] dimensions, + final long[] min) { + final int index = imgLoader.getCellIndex(timepoint, setup, level, min); + return String.format("%s?p=%s/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d", + imgLoader.baseUrl, baseParam, + index, timepoint, setup, level, + dimensions[0], dimensions[1], dimensions[2], + min[0], min[1], min[2]); + } + + + @Override + public VolatileShortArray loadArray(final int timepoint, + final int setup, + final int level, + final int[] dimensions, + final long[] min) throws InterruptedException { + + + if (requestCompressedData) { + return loadArrayFromCompressedDataStream(timepoint, setup, level, dimensions, min); + } + + short[] data = new short[dimensions[0] * dimensions[1] * dimensions[2]]; + try { + final URL url = new URL(constructRequestUrl("cell", timepoint, setup, level, dimensions, min)); + final byte[] buf = new byte[data.length * 2]; + final InputStream urlStream = url.openStream(); - // NOTE(Moravec): Decompression place! - for (int i = 0, l = s.read(buf, 0, buf.length); - l > 0; - i += l, l = s.read(buf, i, buf.length - i)) - ; + //noinspection StatementWithEmptyBody + for (int i = 0, l = urlStream.read(buf, 0, buf.length); + l > 0; + i += l, l = urlStream.read(buf, i, buf.length - i)) + ; for (int i = 0, j = 0; i < data.length; ++i, j += 2) data[i] = (short) (((buf[j] & 0xff) << 8) | (buf[j + 1] & 0xff)); - s.close(); - } - catch ( final MalformedURLException e ) - { - e.printStackTrace(); - } - catch ( final IOException e ) - { - e.printStackTrace(); - } - return new VolatileShortArray( data, true ); - } - - @Override - public int getBytesPerElement() { - return 2; - } + + urlStream.close(); + } catch (final MalformedURLException e) { + e.printStackTrace(); + } catch (final IOException e) { + e.printStackTrace(); + } + return new VolatileShortArray(data, true); + } + + public VolatileShortArray loadArrayFromCompressedDataStream(final int timepoint, + final int setup, + final int level, + final int[] dimensions, + final long[] min) { + + short[] data = null; + try { + final URL url = new URL(constructRequestUrl("cell_qcmp", timepoint, setup, level, dimensions, min)); + + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + + final byte[] buf = new byte[connection.getContentLength()]; + final InputStream urlStream = connection.getInputStream(); + + //noinspection StatementWithEmptyBody + for (int i = 0, l = urlStream.read(buf, 0, buf.length); + l > 0; + i += l, l = urlStream.read(buf, i, buf.length - i)) + ; + + + data = decompressor.decompressStream(urlStream); + + urlStream.close(); + } catch (final Exception e) { + e.printStackTrace(); + } + + return new VolatileShortArray(data, true); + } + + @Override + public int getBytesPerElement() { + return 2; + } + + public void setDataDecompressor(final ImageDecompressor imageDecompressor) { + this.decompressor = imageDecompressor; + requestCompressedData = true; + } }