Skip to content
Snippets Groups Projects
Commit 4a227e80 authored by Vojtech Moravec's avatar Vojtech Moravec
Browse files

Implement data wrapping.

Implement data wrapping for loadBlock variant with valueAt.

We support three different wrapping strategies:
  LeaveBlank
  ClampToEdge
  MirrorerRepeat

Those are based on OpenGL texture wrapping.

Wrapping is neccessary because otherwise border blocks and voxels and quantized with wrong vectors and BigDataViewer recontruction is horrible.
parent bf10676a
No related branches found
No related tags found
No related merge requests found
......@@ -2,12 +2,15 @@ package azgracompress.io.loader;
import azgracompress.data.*;
import javax.print.attribute.standard.RequestingUserName;
import java.io.IOException;
public abstract class BasicLoader {
protected final V3i dims;
protected int threadCount = 1;
private DataWrappingStrategy wrappingStrategy = DataWrappingStrategy.MirroredRepeat;
protected BasicLoader(final V3i datasetDims) {
this.dims = datasetDims;
}
......@@ -16,6 +19,16 @@ public abstract class BasicLoader {
return dims;
}
public DataWrappingStrategy getWrappingStrategy() {
return wrappingStrategy;
}
public void setWrappingStrategy(DataWrappingStrategy strategy) {
wrappingStrategy = strategy;
}
/**
* Abstract method to load specified plane data.
*
......@@ -123,16 +136,60 @@ public abstract class BasicLoader {
return blocks;
}
private void loadBlock(final int[] block, final int planeIndex, final int blockXOffset, final int blockYOffset, final V2i blockDim) {
int srcX, srcY;
for (int y = 0; y < blockDim.getY(); y++) {
srcY = blockYOffset + y;
if (srcY >= dims.getY())
break;
// Row overflow
if (srcY >= dims.getY()) {
if (wrappingStrategy == DataWrappingStrategy.LeaveBlank)
break;
if (wrappingStrategy == DataWrappingStrategy.ClampToEdge) {
final int srcRow = dims.getY() - 1;
final int dstOffset = y * blockDim.getX();
for (int x = 0; x < blockDim.getX(); x++) {
srcX = (blockXOffset + x);
if (srcX >= dims.getX())
srcX = dims.getX() - 1;
block[dstOffset + x] = valueAt(planeIndex, Block.index(srcX, srcRow, dims.getX()));
}
continue;
} else if (wrappingStrategy == DataWrappingStrategy.MirroredRepeat) {
final int srcRow = dims.getY() - ((srcY - dims.getY()) + 1);
final int dstOffset = y * blockDim.getX();
for (int x = 0; x < blockDim.getX(); x++) {
srcX = (blockXOffset + x);
if (srcX >= dims.getX())
srcX = dims.getX() - 1;
block[dstOffset + x] = valueAt(planeIndex, Block.index(srcX, srcRow, dims.getX()));
}
continue;
}
}
for (int x = 0; x < blockDim.getX(); x++) {
srcX = blockXOffset + x;
if (srcX >= dims.getX())
break;
// Column overflow.
if (srcX >= dims.getX()) {
if (wrappingStrategy == DataWrappingStrategy.LeaveBlank)
break;
if (wrappingStrategy == DataWrappingStrategy.ClampToEdge) {
block[Block.index(x, y, blockDim.getX())] = valueAt(planeIndex, Block.index(dims.getX() - 1, srcY, dims.getX()));
continue;
} else if (wrappingStrategy == DataWrappingStrategy.MirroredRepeat) {
block[Block.index(x, y, blockDim.getX())] =
valueAt(planeIndex, Block.index(dims.getX() - ((srcX - dims.getX()) + 1), srcY, dims.getX()));
continue;
}
}
block[Block.index(x, y, blockDim.getX())] = valueAt(planeIndex, Block.index(srcX, srcY, dims.getX()));
}
}
......@@ -142,8 +199,10 @@ public abstract class BasicLoader {
int srcX, srcY;
for (int y = 0; y < blockDim.getY(); y++) {
srcY = blockYOffset + y;
if (srcY >= dims.getY())
break;
if (srcY >= dims.getY()) {
// handleBlockRowOverflow(block, blockDim, y, srcY);
continue;
}
for (int x = 0; x < blockDim.getX(); x++) {
srcX = blockXOffset + x;
if (srcX >= dims.getX())
......
package azgracompress.io.loader;
/**
* What to do when blocks or voxels extend outside the source image. These parameters are based on OpenGL texture wrapping options.
*/
public enum DataWrappingStrategy {
/**
* Pixels outside the source range are left blank, value 0.
*/
LeaveBlank,
/**
* The edge value is repeated.
*/
ClampToEdge,
/**
* Pixels will be repeated by mirrored strategy.
*/
MirroredRepeat
}
......@@ -22,6 +22,20 @@ public interface IPlaneLoader {
return false;
}
/**
* Get data wrapping strategy configured for this loader.
*
* @return Wrapping strategy.
*/
DataWrappingStrategy getWrappingStrategy();
/**
* Configure data wrapping strategy for this loader.
*
* @param strategy Wrapping strategy.
*/
void setWrappingStrategy(DataWrappingStrategy strategy);
/**
* Get dimensions of the image, for which the loader was created.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment