Skip to content
Snippets Groups Projects
Commit 0b976466 authored by Vojtěch Moravec's avatar Vojtěch Moravec
Browse files

Code revision in Chunk3D, still need work.

parent c1f487ed
Branches
No related tags found
No related merge requests found
package azgracompress.data; package azgracompress.data;
import azgracompress.utilities.TypeConverter; import java.util.Arrays;
public class Chunk3D { public class Chunk3D {
private final int FILL_VALUE = 0;
private final int[] data; private final int[] data;
private final V3i dims; private final V3i dims;
private final V3l offset;
public Chunk3D(final V3i dims, final V3l offset, final int[] data) { public Chunk3D(final V3i dims, final int[] data) {
this.dims = dims; this.dims = dims;
this.data = data; this.data = data;
this.offset = offset;
assert (data.length == (dims.getX() * dims.getY() * dims.getZ())) : "Wrong box data."; assert (data.length == (dims.getX() * dims.getY() * dims.getZ())) : "Wrong box data.";
} }
public Chunk3D(final V3i chunkDdims, final V3l offset) { public Chunk3D(final V3i chunkDims) {
this(chunkDdims, offset, new int[chunkDdims.getX() * chunkDdims.getY() * chunkDdims.getZ()]); this(chunkDims, new int[(int) chunkDims.multiplyTogether()]);
} }
/** /**
...@@ -28,24 +27,7 @@ public class Chunk3D { ...@@ -28,24 +27,7 @@ public class Chunk3D {
* @return Index inside data array. * @return Index inside data array.
*/ */
private int index(final int x, final int y, final int z) { private int index(final int x, final int y, final int z) {
assert (x >= 0 && x < dims.getX()) : "Index X out of bounds."; return index(x, y, z, dims);
assert (y >= 0 && y < dims.getY()) : "Index Y out of bounds.";
assert (z >= 0 && z < dims.getZ()) : "Index Z out of bounds.";
/// NOTE In higher dimensions, the last dimension specified is the fastest changing on disk.
// So if we have a four dimensional dataset A, then the first element on disk would be A[0][0][0][0],
// the second A[0][0][0][1], the third A[0][0][0][2], and so on.
// SOURCE: https://support.hdfgroup.org/HDF5/doc/Advanced/Chunking/index.html
/*
0 1 2 3 4 5 6 7
A[0][0][0] A[0][0][1] A[0][1][0] A[0][1][1] A[1][0][0] A[1][0][1] A[1][1][0] A[1][1][1]
*/
// TODO(Moravec): Test which version is correct!
//final int index = (x * (dims.getY() * dims.getZ())) + (y * dims.getZ()) + z;
final int index = (z * (dims.getX() * dims.getY())) + (y * dims.getX()) + x;
assert (index < data.length) : "Index calculation is wrong";
return index;
} }
/** /**
...@@ -58,14 +40,27 @@ public class Chunk3D { ...@@ -58,14 +40,27 @@ public class Chunk3D {
* @return Index inside chunk dimension data array. * @return Index inside chunk dimension data array.
*/ */
private int index(final int x, final int y, final int z, final V3i chunkDims) { private int index(final int x, final int y, final int z, final V3i chunkDims) {
if (((x < 0) || (x >= chunkDims.getX())) || (y < 0) || (y >= chunkDims.getY()) || (z < 0) || (z >= chunkDims.getZ())) { assert (x >= 0 && x < dims.getX()) : "Index X out of bounds.";
throw new IndexOutOfBoundsException("One of index x,y,z is out of bounds of the 3D box"); assert (y >= 0 && y < dims.getY()) : "Index Y out of bounds.";
} assert (z >= 0 && z < dims.getZ()) : "Index Z out of bounds.";
// TODO(Moravec): Test which version is correct! // NOTE(Moravec): Description of the following calculation
//final int index = (x * (chunkDims.getY() * chunkDims.getZ())) + (y * chunkDims.getZ()) + z; // plane index * plane pixel count
final int index = (z * (chunkDims.getX() * chunkDims.getY())) + (y * chunkDims.getX()) + x; // | |
return index; // V V
// planeOffset = chunkDims.getZ() * (chunkDims.getX() * chunkDims.getY())
// row * pixels in row
// | |
// V V
// rowOffset = y * chunkDims.getX();
// column
// |
// V
// colOffset = x;
return (chunkDims.getZ() * (chunkDims.getX() * chunkDims.getY())) + (y * chunkDims.getX()) + x;
} }
...@@ -81,105 +76,69 @@ public class Chunk3D { ...@@ -81,105 +76,69 @@ public class Chunk3D {
return dims; return dims;
} }
public V3l getOffset() {
return offset;
}
@Override @Override
public String toString() { public String toString() {
return String.format("3D box %s %d values", dims.toString(), data.length); return String.format("3D box %s %d values", dims.toString(), data.length);
} }
public Chunk3D[] divideIntoChunks(final V3i chunkDims) { public int[][] divideInto3DVectors(final V3i qVectorDims) {
final int chunkSize = qVectorDims.getX() * qVectorDims.getY() * qVectorDims.getZ();
final int chunkCount = calculateRequiredChunkCount(qVectorDims);
final int xSize = dims.getX(); int[][] vectors = new int[chunkCount][chunkSize];
final int ySize = dims.getY(); int vecIndex = 0;
final int zSize = dims.getZ();
final int chunkCount = getRequiredChunkCount(chunkDims); for (int chunkZOffset = 0; chunkZOffset < dims.getZ(); chunkZOffset += qVectorDims.getZ()) {
for (int chunkYOffset = 0; chunkYOffset < dims.getY(); chunkYOffset += qVectorDims.getY()) {
Chunk3D[] chunks = new Chunk3D[chunkCount]; for (int chunkXOffset = 0; chunkXOffset < dims.getX(); chunkXOffset += qVectorDims.getX()) {
int chunkIndex = 0; copyDataToVector(vectors[vecIndex++], qVectorDims, chunkXOffset, chunkYOffset, chunkZOffset);
for (int chunkZOffset = 0; chunkZOffset < zSize; chunkZOffset += chunkDims.getZ()) {
for (int chunkYOffset = 0; chunkYOffset < ySize; chunkYOffset += chunkDims.getY()) {
for (int chunkXOffset = 0; chunkXOffset < xSize; chunkXOffset += chunkDims.getX()) {
chunks[chunkIndex++] = copyToChunk(chunkDims, new V3i(chunkXOffset, chunkYOffset, chunkZOffset));
} }
} }
} }
return chunks; return vectors;
} }
private int getRequiredChunkCount(final V3i chunkDims) { private int calculateRequiredChunkCount(final V3i chunkDims) {
final int xChunkCount = (int) Math.ceil(dims.getX() / (double) chunkDims.getX()); return calculateRequiredChunkCount(dims, chunkDims);
final int yChunkCount = (int) Math.ceil(dims.getY() / (double) chunkDims.getY());
final int zChunkCount = (int) Math.ceil(dims.getZ() / (double) chunkDims.getZ());
final int expectedChunkCount = xChunkCount * yChunkCount * zChunkCount;
return expectedChunkCount;
} }
public void reconstructFromChunks(final Chunk3D[] chunks) { public static int calculateRequiredChunkCount(final V3i imageDims, final V3i chunkDims) {
assert (chunks.length > 0) : "No chunks in reconstruct"; final int xChunkCount = (int) Math.ceil((double) imageDims.getX() / (double) chunkDims.getX());
final V3i chunkDims = chunks[0].getDims(); final int yChunkCount = (int) Math.ceil((double) imageDims.getY() / (double) chunkDims.getY());
final int zChunkCount = (int) Math.ceil((double) imageDims.getZ() / (double) chunkDims.getZ());
assert (getRequiredChunkCount(chunkDims) == chunks.length) : "Wrong chunk count in reconstruct"; return (xChunkCount * yChunkCount * zChunkCount);
for (final Chunk3D chunk : chunks) {
copyFromChunk(chunk);
}
} }
private boolean isInside(final int x, final int y, final int z) { private boolean isInside(final int x, final int y, final int z) {
return (((x >= 0) && (x < dims.getX())) && (y >= 0) && (y < dims.getY()) && (z >= 0) && (z < dims.getZ())); return (((x >= 0) && (x < dims.getX())) && (y >= 0) && (y < dims.getY()) && (z >= 0) && (z < dims.getZ()));
} }
private void copyFromChunk(final Chunk3D chunk) { /**
* Copy this chunk data to chunk vector.
final V3i chunkDims = chunk.getDims(); *
final V3l localOffset = chunk.getOffset(); * @param vector Chunk vector.
int dstX, dstY, dstZ; * @param qVectorDims Dimensions of the vector.
* @param chunkXOffset Chunk X offset
for (int chunkZ = 0; chunkZ < chunkDims.getZ(); chunkZ++) { * @param chunkYOffset Chunk Y offset.
dstZ = (int) localOffset.getZ() + chunkZ; * @param chunkZOffset Chunk Z offset.
for (int chunkY = 0; chunkY < chunkDims.getY(); chunkY++) { */
dstY = (int) localOffset.getY() + chunkY; private void copyDataToVector(int[] vector,
for (int chunkX = 0; chunkX < chunkDims.getX(); chunkX++) { final V3i qVectorDims,
dstX = (int) localOffset.getX() + chunkX; final int chunkXOffset,
final int chunkYOffset,
// NOTE(Moravec): Negating this expression! final int chunkZOffset) {
// If dst coordinates are NOT outside bounds, copy the value.
if (!(dstX >= dims.getX() || dstY >= dims.getY() || dstZ >= dims.getZ())) {
setValueAt(dstX, dstY, dstZ, chunk.getValueAt(chunkX, chunkY, chunkZ));
}
}
}
}
}
private Chunk3D copyToChunk(final V3i chunkDims, final V3i chunkOffset) {
int[] chunkData = new int[(int) (chunkDims.getX() * chunkDims.getY() * chunkDims.getZ())];
final int FILL_VALUE = 0;
int srcX, srcY, srcZ; int srcX, srcY, srcZ;
for (int z = 0; z < qVectorDims.getZ(); z++) {
for (int z = 0; z < chunkDims.getZ(); z++) { srcZ = chunkZOffset + z;
srcZ = chunkOffset.getZ() + z; for (int y = 0; y < qVectorDims.getY(); y++) {
for (int y = 0; y < chunkDims.getY(); y++) { srcY = chunkYOffset + y;
srcY = chunkOffset.getY() + y; for (int x = 0; x < qVectorDims.getX(); x++) {
for (int x = 0; x < chunkDims.getX(); x++) { srcX = chunkXOffset + x;
srcX = chunkOffset.getX() + x; final int dstIndex = index(x, y, z, qVectorDims);
chunkData[index(x, y, z, chunkDims)] = isInside(srcX, srcY, srcZ) ? vector[dstIndex] = isInside(srcX, srcY, srcZ) ? data[index(srcX, srcY, srcZ)] : FILL_VALUE;
data[index(srcX, srcY, srcZ)] :
FILL_VALUE;
} }
} }
} }
// NOTE(Moravec): We will save only local offset inside current box, which will be used
// to reconstruct the original box.
final Chunk3D chunk = new Chunk3D(chunkDims, chunkOffset.toV3l(), chunkData);
return chunk;
} }
@Override @Override
...@@ -188,8 +147,6 @@ public class Chunk3D { ...@@ -188,8 +147,6 @@ public class Chunk3D {
final Chunk3D otherChunk = (Chunk3D) obj; final Chunk3D otherChunk = (Chunk3D) obj;
if (data.length != otherChunk.data.length) { if (data.length != otherChunk.data.length) {
return false; return false;
} else if (!(offset.equals(otherChunk.offset))) {
return false;
} else { } else {
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
if (data[i] != otherChunk.data[i]) { if (data[i] != otherChunk.data[i]) {
...@@ -208,8 +165,6 @@ public class Chunk3D { ...@@ -208,8 +165,6 @@ public class Chunk3D {
} }
public void zeroData() { public void zeroData() {
for (int i = 0; i < data.length; i++) { Arrays.fill(data, 0);
data[i] = 0;
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment