diff --git a/src/main/java/azgracompress/io/loader/BasicLoader.java b/src/main/java/azgracompress/io/loader/BasicLoader.java index 3e11384b046d91f27c083c4367c5c6fb36294e78..04330f0900beacee7aadf381aa17d58ad553dfae 100644 --- a/src/main/java/azgracompress/io/loader/BasicLoader.java +++ b/src/main/java/azgracompress/io/loader/BasicLoader.java @@ -26,11 +26,67 @@ public abstract class BasicLoader { public abstract int[] loadPlaneData(final int plane) throws IOException; protected int valueAt(final int plane, final int offset) { + new Exception().printStackTrace(System.err); assert (false) : "Unimplemented overload of BasicLoader::valueAt()"; return Integer.MIN_VALUE; } - protected int[][] loadBlocksImplLoadPlaneData(final V2i blockDim, final Range<Integer> planeRange) throws IOException { + protected int[][] loadRowVectorsImplByLoadPlaneData(final int vectorSize, final Range<Integer> planeRange) throws IOException { + final int rowVectorCount = (int) Math.ceil((double) dims.getX() / (double) vectorSize); + final int vectorCount = dims.getZ() * dims.getY() * rowVectorCount; + + int[][] rowVectors = new int[vectorCount][vectorSize]; + + int vectorIndex = 0; + int baseX; + + for (int plane = planeRange.getFrom(); plane < planeRange.getTo(); plane++) { + final int[] planeData = loadPlaneData(plane); + for (int row = 0; row < dims.getY(); row++) { + for (int rowVectorIndex = 0; rowVectorIndex < rowVectorCount; rowVectorIndex++) { + // Copy single vector. + baseX = rowVectorIndex * vectorSize; + + for (int vectorX = 0; vectorX < vectorSize; vectorX++) { + if (baseX + vectorX >= dims.getY()) + break; + rowVectors[vectorIndex][vectorX] = planeData[Chunk2D.index((baseX + vectorX), row, dims.getY())]; + } + ++vectorIndex; + } + } + } + return rowVectors; + } + + protected int[][] loadRowVectorsImplByValueAt(final int vectorSize, final Range<Integer> planeRange) { + final int rowVectorCount = (int) Math.ceil((double) dims.getX() / (double) vectorSize); + final int vectorCount = dims.getZ() * dims.getY() * rowVectorCount; + + int[][] rowVectors = new int[vectorCount][vectorSize]; + + int vectorIndex = 0; + int baseX; + + for (int plane = planeRange.getFrom(); plane < planeRange.getTo(); plane++) { + for (int row = 0; row < dims.getY(); row++) { + for (int rowVectorIndex = 0; rowVectorIndex < rowVectorCount; rowVectorIndex++) { + // Copy single vector. + baseX = rowVectorIndex * vectorSize; + + for (int vectorX = 0; vectorX < vectorSize; vectorX++) { + if (baseX + vectorX >= dims.getY()) + break; + rowVectors[vectorIndex][vectorX] = valueAt(plane, Chunk2D.index((baseX + vectorX), row, dims.getY())); + } + ++vectorIndex; + } + } + } + return rowVectors; + } + + protected int[][] loadBlocksImplByLoadPlaneData(final V2i blockDim, final Range<Integer> planeRange) throws IOException { final int blockSize = blockDim.multiplyTogether(); final int planeCount = planeRange.getTo() - planeRange.getFrom(); final int blockCount = planeCount * Chunk2D.calculateRequiredChunkCount(dims.toV2i(), blockDim); diff --git a/src/main/java/azgracompress/io/loader/IPlaneLoader.java b/src/main/java/azgracompress/io/loader/IPlaneLoader.java index 7e20bac003cf6680bbe604457a6ca22a1cfebe2a..db338cf36b6dffa12b8b59b228e0ac968495f555 100644 --- a/src/main/java/azgracompress/io/loader/IPlaneLoader.java +++ b/src/main/java/azgracompress/io/loader/IPlaneLoader.java @@ -54,6 +54,27 @@ public interface IPlaneLoader { */ int[] loadAllPlanesU16Data() throws IOException; + /** + * Load row vectors from the entire dataset. + * + * @param vectorSize Width of the row vector. + * @return Row vector data from the entire dataset. + * @throws IOException When fails to load plane data. + */ + default int[][] loadRowVectors(final int vectorSize) throws IOException { + return loadRowVectors(vectorSize, new Range<>(0, getImageDimensions().getZ())); + } + + /** + * Load row vectors from specified plane range in the dataset. + * + * @param vectorSize Width of the row vector. + * @param planeRange Source plane range. + * @return Row vector data from the specified plane range. + * @throws IOException When fails to load plane data. + */ + int[][] loadRowVectors(final int vectorSize, final Range<Integer> planeRange) throws IOException; + /** * Load blocks from the entire dataset. * diff --git a/src/main/java/azgracompress/io/loader/ImageJBufferLoader.java b/src/main/java/azgracompress/io/loader/ImageJBufferLoader.java index c43bcfcdf80d35046e8ed3422190767d5280bb86..baea7c955fcc79e482a1e7a23f0cd186177858f9 100644 --- a/src/main/java/azgracompress/io/loader/ImageJBufferLoader.java +++ b/src/main/java/azgracompress/io/loader/ImageJBufferLoader.java @@ -93,7 +93,12 @@ public final class ImageJBufferLoader extends BasicLoader implements IPlaneLoade } @Override - public int[][] loadBlocks(V2i blockDim, Range<Integer> planeRange) throws IOException { + public int[][] loadRowVectors(final int vectorSize, final Range<Integer> planeRange) { + return loadRowVectorsImplByValueAt(vectorSize, planeRange); + } + + @Override + public int[][] loadBlocks(V2i blockDim, Range<Integer> planeRange) { return loadBlocksImplByValueAt(blockDim, planeRange); } diff --git a/src/main/java/azgracompress/io/loader/RawDataLoader.java b/src/main/java/azgracompress/io/loader/RawDataLoader.java index 701a509c1591a99ac7a3f9f7cc3d76a9b4ed7433..385f17f8d66343b53f0b9d91c09d40ed9b7275c6 100644 --- a/src/main/java/azgracompress/io/loader/RawDataLoader.java +++ b/src/main/java/azgracompress/io/loader/RawDataLoader.java @@ -117,9 +117,14 @@ public final class RawDataLoader extends BasicLoader implements IPlaneLoader { return values; } + @Override + public int[][] loadRowVectors(final int vectorSize, final Range<Integer> planeRange) throws IOException { + return loadRowVectorsImplByLoadPlaneData(vectorSize, planeRange); + } + @Override public int[][] loadBlocks(V2i blockDim, Range<Integer> planeRange) throws IOException { - return loadBlocksImplLoadPlaneData(blockDim, planeRange); + return loadBlocksImplByLoadPlaneData(blockDim, planeRange); } @Override diff --git a/src/main/java/azgracompress/io/loader/SCIFIOLoader.java b/src/main/java/azgracompress/io/loader/SCIFIOLoader.java index 4e151663e18d1fc80cd10c4b383ed97aadc54c08..7b4d0128f5f70f2deca0be8068672bd5442e7b11 100644 --- a/src/main/java/azgracompress/io/loader/SCIFIOLoader.java +++ b/src/main/java/azgracompress/io/loader/SCIFIOLoader.java @@ -16,10 +16,6 @@ public final class SCIFIOLoader extends BasicLoader implements IPlaneLoader { private final FileInputData inputDataInfo; private final Reader reader; - // Current plane buffer - private int currentPlaneIndex = -1; - private int[] currentPlaneData; - /** * Create SCIFIO reader from input file. * @@ -33,26 +29,6 @@ public final class SCIFIOLoader extends BasicLoader implements IPlaneLoader { this.reader = ScifioWrapper.getReader(this.inputDataInfo.getFilePath()); } -// @Override -// protected int valueAt(int plane, int offset) { -// // TODO(Moravec): Measure if caching the current plane byte buffer make any sense. -// if (plane != currentPlaneIndex) { -// currentPlaneIndex = plane; -// try { -// currentPlaneData = TypeConverter.unsignedShortBytesToIntArray(reader.openPlane(0, currentPlaneIndex).getBytes()); -// } catch (FormatException e) { -// System.err.println(e.toString()); -// e.printStackTrace(); -// assert (false) : "FormatException in SCIFIOLoader::valueAt()"; -// } catch (IOException e) { -// System.err.println(e.toString()); -// e.printStackTrace(); -// assert (false) : "IOException in SCIFIOLoader::valueAt()"; -// } -// } -// return currentPlaneData[offset]; -// } - @Override public int[] loadPlaneData(final int plane) throws IOException { byte[] planeBytes; @@ -129,9 +105,14 @@ public final class SCIFIOLoader extends BasicLoader implements IPlaneLoader { return values; } + @Override + public int[][] loadRowVectors(final int vectorSize, final Range<Integer> planeRange) throws IOException { + return loadRowVectorsImplByLoadPlaneData(vectorSize, planeRange); + } + @Override public int[][] loadBlocks(V2i blockDim, Range<Integer> planeRange) throws IOException { - return loadBlocksImplLoadPlaneData(blockDim, planeRange); + return loadBlocksImplByLoadPlaneData(blockDim, planeRange); } @Override