diff --git a/src/main/java/azgracompress/compression/IImageCompressor.java b/src/main/java/azgracompress/compression/IImageCompressor.java
index 7752a28250ffdd21b1cc22045bb3ec7b1ec89336..d0165c9bc93ff5cc78e570edc508e450fb02e128 100644
--- a/src/main/java/azgracompress/compression/IImageCompressor.java
+++ b/src/main/java/azgracompress/compression/IImageCompressor.java
@@ -4,12 +4,10 @@ import java.io.DataOutputStream;
public interface IImageCompressor {
- // TODO(Moravec): Replace default Exception with better Exception type.
-
/**
* Compress the image planes.
* @param compressStream Compressed data stream.
- * @throws Exception when compression fails.
+ * @throws ImageCompressionException when compression fails.
*/
- void compress(DataOutputStream compressStream) throws Exception;
+ void compress(DataOutputStream compressStream) throws ImageCompressionException;
}
diff --git a/src/main/java/azgracompress/compression/IImageDecompressor.java b/src/main/java/azgracompress/compression/IImageDecompressor.java
index a9516bd900d3bca99630410662fd2350c6b7a256..e21bc41e52925d86942af81fc4b40841301f6ff0 100644
--- a/src/main/java/azgracompress/compression/IImageDecompressor.java
+++ b/src/main/java/azgracompress/compression/IImageDecompressor.java
@@ -20,10 +20,10 @@ public interface IImageDecompressor {
* @param compressedStream Input stream of compressed data.
* @param decompressStream Output stream for decompressed data.
* @param header QCMPFile information.
- * @throws Exception when decompression fails.
+ * @throws ImageDecompressionException when decompression fails.
*/
void decompress(DataInputStream compressedStream,
DataOutputStream decompressStream,
- final QCMPFileHeader header) throws Exception;
+ final QCMPFileHeader header) throws ImageDecompressionException;
}
diff --git a/src/main/java/azgracompress/compression/ImageCompressionException.java b/src/main/java/azgracompress/compression/ImageCompressionException.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fe5e34543266f80492f9236e8ffe5e087051878
--- /dev/null
+++ b/src/main/java/azgracompress/compression/ImageCompressionException.java
@@ -0,0 +1,24 @@
+package azgracompress.compression;
+
+public class ImageCompressionException extends Exception {
+ private final Exception innerException;
+
+ public ImageCompressionException(final String message, final Exception innerException) {
+ super(message);
+ this.innerException = innerException;
+ }
+
+ public ImageCompressionException(final String message) {
+ super(message);
+ this.innerException = null;
+ }
+
+ @Override
+ public String getMessage() {
+ String msg = super.getMessage();
+ if (msg != null && innerException != null) {
+ msg += "\nInner exception:\n" + innerException.getMessage();
+ }
+ return msg;
+ }
+}
diff --git a/src/main/java/azgracompress/compression/ImageCompressor.java b/src/main/java/azgracompress/compression/ImageCompressor.java
index 80f35e29d6b04575ffb5bc3bd1334da18e0b6d05..866c41dc611dc17a507d86f457e794aea88a7be3 100644
--- a/src/main/java/azgracompress/compression/ImageCompressor.java
+++ b/src/main/java/azgracompress/compression/ImageCompressor.java
@@ -62,10 +62,12 @@ public class ImageCompressor extends CompressorDecompressorBase {
reportCompressionRatio(header, compressStream.size());
}
- } catch (Exception ex) {
+ } catch (ImageCompressionException ex) {
System.err.println(ex.getMessage());
return false;
-
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
}
return true;
}
diff --git a/src/main/java/azgracompress/compression/ImageDecompressionException.java b/src/main/java/azgracompress/compression/ImageDecompressionException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ed88cc81bd42c3990c65748a23715005fbd8213
--- /dev/null
+++ b/src/main/java/azgracompress/compression/ImageDecompressionException.java
@@ -0,0 +1,24 @@
+package azgracompress.compression;
+
+public class ImageDecompressionException extends Exception {
+ private final Exception innerException;
+
+ public ImageDecompressionException(final String message, final Exception innerException) {
+ super(message);
+ this.innerException = innerException;
+ }
+
+ public ImageDecompressionException(final String message) {
+ super(message);
+ this.innerException = null;
+ }
+
+ @Override
+ public String getMessage() {
+ String msg = super.getMessage();
+ if (msg != null && innerException != null) {
+ msg += "\nInner exception:\n" + innerException.getMessage();
+ }
+ return msg;
+ }
+}
diff --git a/src/main/java/azgracompress/compression/ImageDecompressor.java b/src/main/java/azgracompress/compression/ImageDecompressor.java
index 30993f70f0cadbb48b85846c3b5810af942b67c5..badbbfa272e538afaeb4951693e23b0e7bbe4a28 100644
--- a/src/main/java/azgracompress/compression/ImageDecompressor.java
+++ b/src/main/java/azgracompress/compression/ImageDecompressor.java
@@ -62,8 +62,7 @@ public class ImageDecompressor extends CompressorDecompressorBase {
try (FileInputStream fileInputStream = new FileInputStream(options.getInputFile());
DataInputStream dataInputStream = new DataInputStream(fileInputStream)) {
header = readQCMPFileHeader(dataInputStream);
- }
- catch (IOException ioEx){
+ } catch (IOException ioEx) {
ioEx.printStackTrace();
return "";
}
@@ -154,9 +153,11 @@ public class ImageDecompressor extends CompressorDecompressorBase {
try (FileOutputStream fos = new FileOutputStream(options.getOutputFile(), false);
DataOutputStream decompressStream = new DataOutputStream(fos)) {
+
imageDecompressor.decompress(dataInputStream, decompressStream, header);
- } catch (Exception ex) {
- ex.printStackTrace();
+
+ } catch (ImageDecompressionException ex) {
+ System.err.println(ex.getMessage());
return false;
}
diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java
index 2181a7a58b079859dd9548c4a84e7a5828fb998d..314dbfdb79ccc72b3eb09d0f48d2676f19e93f2c 100644
--- a/src/main/java/azgracompress/compression/SQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/SQImageCompressor.java
@@ -35,13 +35,17 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
*
* @param quantizer Quantizer used for compression of the image.
* @param compressStream Compressed data stream.
- * @throws IOException when writing to the stream fails.
+ * @throws ImageCompressionException when writing to the stream fails.
*/
private void writeCodebookToOutputStream(final ScalarQuantizer quantizer,
- DataOutputStream compressStream) throws IOException {
+ DataOutputStream compressStream) throws ImageCompressionException {
final int[] centroids = quantizer.getCentroids();
- for (final int quantizationValue : centroids) {
- compressStream.writeShort(quantizationValue);
+ try {
+ for (final int quantizationValue : centroids) {
+ compressStream.writeShort(quantizationValue);
+ }
+ } catch (IOException ioEx) {
+ throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx);
}
if (options.isVerbose()) {
Log("Wrote quantization values to compressed stream.");
@@ -52,21 +56,29 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
* Compress the image file specified by parsed CLI options using scalar quantization.
*
* @param compressStream Stream to which compressed data will be written.
- * @throws Exception When compress process fails.
+ * @throws ImageCompressionException When compress process fails.
*/
- public void compress(DataOutputStream compressStream) throws Exception {
+ public void compress(DataOutputStream compressStream) throws ImageCompressionException {
ScalarQuantizer quantizer = null;
Stopwatch stopwatch = new Stopwatch();
if (options.hasReferencePlaneIndex()) {
stopwatch.restart();
- final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
- options.getImageDimension(),
- options.getReferencePlaneIndex());
+ ImageU16 referencePlane = null;
+ try {
+ referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
+ options.getImageDimension(),
+ options.getReferencePlaneIndex());
+ } catch (Exception ex) {
+ throw new ImageCompressionException("Unable to load reference plane data.", ex);
+ }
+
Log(String.format("Training scalar quantizer from reference plane %d.", options.getReferencePlaneIndex()));
quantizer = trainScalarQuantizerFromData(referencePlane.getData());
stopwatch.stop();
+
writeCodebookToOutputStream(quantizer, compressStream);
+
Log("Reference codebook created in: " + stopwatch.getElapsedTimeString());
}
@@ -74,9 +86,16 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
for (final int planeIndex : planeIndices) {
stopwatch.restart();
Log(String.format("Loading plane %d.", planeIndex));
- final ImageU16 plane = RawDataIO.loadImageU16(options.getInputFile(),
- options.getImageDimension(),
- planeIndex);
+
+ ImageU16 plane = null;
+
+ try {
+ plane = RawDataIO.loadImageU16(options.getInputFile(),
+ options.getImageDimension(),
+ planeIndex);
+ } catch (Exception ex) {
+ throw new ImageCompressionException("Unable to load plane data.", ex);
+ }
if (!options.hasReferencePlaneIndex()) {
Log(String.format("Training scalar quantizer from plane %d.", planeIndex));
@@ -91,8 +110,8 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
try (OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048)) {
outBitStream.write(indices);
- } catch (IOException ioEx) {
- ioEx.printStackTrace();
+ } catch (Exception ex) {
+ throw new ImageCompressionException("Unable to write indices to OutBitStream.", ex);
}
stopwatch.stop();
Log("Plane time: " + stopwatch.getElapsedTimeString());
diff --git a/src/main/java/azgracompress/compression/SQImageDecompressor.java b/src/main/java/azgracompress/compression/SQImageDecompressor.java
index 0c6cbea4899fcd294732663aea27c56d44638569..0eb6dbc8a88c81e8d8f821d9cbf5551dbbda157e 100644
--- a/src/main/java/azgracompress/compression/SQImageDecompressor.java
+++ b/src/main/java/azgracompress/compression/SQImageDecompressor.java
@@ -15,10 +15,15 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I
super(options);
}
- private int[] readScalarQuantizationValues(DataInputStream compressedStream, final int n) throws IOException {
+ private int[] readScalarQuantizationValues(DataInputStream compressedStream,
+ final int n) throws ImageDecompressionException {
int[] quantizationValues = new int[n];
- for (int i = 0; i < n; i++) {
- quantizationValues[i] = compressedStream.readUnsignedShort();
+ try {
+ for (int i = 0; i < n; i++) {
+ quantizationValues[i] = compressedStream.readUnsignedShort();
+ }
+ } catch (IOException ioEx) {
+ throw new ImageDecompressionException("Unable to read quantization values from compressed stream.", ioEx);
}
return quantizationValues;
}
@@ -44,7 +49,7 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I
@Override
public void decompress(DataInputStream compressedStream,
DataOutputStream decompressStream,
- QCMPFileHeader header) throws Exception {
+ QCMPFileHeader header) throws ImageDecompressionException {
final int codebookSize = (int) Math.pow(2, header.getBitsPerPixel());
final int planeCountForDecompression = header.getImageSizeZ();
@@ -68,18 +73,31 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I
assert (quantizationValues != null);
Log(String.format("Decompressing plane %d...", planeIndex));
- InBitStream inBitStream = new InBitStream(compressedStream, header.getBitsPerPixel(), planeIndicesDataSize);
- inBitStream.readToBuffer();
- inBitStream.setAllowReadFromUnderlyingStream(false);
- final int[] indices = inBitStream.readNValues(planePixelCount);
-
- int[] decompressedValues = new int[planePixelCount];
- for (int i = 0; i < planePixelCount; i++) {
- decompressedValues[i] = quantizationValues[indices[i]];
+ byte[] decompressedPlaneData = null;
+ try (InBitStream inBitStream = new InBitStream(compressedStream,
+ header.getBitsPerPixel(),
+ planeIndicesDataSize)) {
+ inBitStream.readToBuffer();
+ inBitStream.setAllowReadFromUnderlyingStream(false);
+ final int[] indices = inBitStream.readNValues(planePixelCount);
+
+ int[] decompressedValues = new int[planePixelCount];
+ for (int i = 0; i < planePixelCount; i++) {
+ decompressedValues[i] = quantizationValues[indices[i]];
+ }
+ decompressedPlaneData =
+ TypeConverter.unsignedShortArrayToByteArray(decompressedValues, false);
+
+
+ } catch (Exception ex) {
+ throw new ImageDecompressionException("Unable to read indices from InBitStream.", ex);
+ }
+ try {
+ decompressStream.write(decompressedPlaneData);
+ } catch (IOException e) {
+ throw new ImageDecompressionException("Unable to write decompressed data to decompress stream.", e);
}
- final byte[] decompressedPlaneData = TypeConverter.unsignedShortArrayToByteArray(decompressedValues, false);
- decompressStream.write(decompressedPlaneData);
stopwatch.stop();
Log(String.format("Decompressed plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString()));
}
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
index 312cb18f542e2319a62c2228df6bda6dd7ef7dc6..cffc85682cede5cf7526d3d4d6a1dc5debe76bfc 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -56,16 +56,20 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
*
* @param quantizer Quantizer with the codebook.
* @param compressStream Stream with compressed data.
- * @throws IOException When unable to write quantizer.
+ * @throws ImageCompressionException When unable to write quantizer.
*/
private void writeQuantizerToCompressStream(final VectorQuantizer quantizer,
- DataOutputStream compressStream) throws IOException {
+ DataOutputStream compressStream) throws ImageCompressionException {
final CodebookEntry[] codebook = quantizer.getCodebook();
- for (final CodebookEntry entry : codebook) {
- final int[] entryVector = entry.getVector();
- for (final int vecVal : entryVector) {
- compressStream.writeShort(vecVal);
+ try {
+ for (final CodebookEntry entry : codebook) {
+ final int[] entryVector = entry.getVector();
+ for (final int vecVal : entryVector) {
+ compressStream.writeShort(vecVal);
+ }
}
+ } catch (IOException ioEx) {
+ throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx);
}
if (options.isVerbose()) {
Log("Wrote quantization vectors to compressed stream.");
@@ -76,16 +80,22 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
* Compress the image file specified by parsed CLI options using vector quantization.
*
* @param compressStream Stream to which compressed data will be written.
- * @throws Exception When compress process fails.
+ * @throws ImageCompressionException When compress process fails.
*/
- public void compress(DataOutputStream compressStream) throws Exception {
+ public void compress(DataOutputStream compressStream) throws ImageCompressionException {
VectorQuantizer quantizer = null;
Stopwatch stopwatch = new Stopwatch();
if (options.hasReferencePlaneIndex()) {
stopwatch.restart();
- final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
- options.getImageDimension(),
- options.getReferencePlaneIndex());
+
+ ImageU16 referencePlane = null;
+ try {
+ referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
+ options.getImageDimension(),
+ options.getReferencePlaneIndex());
+ } catch (Exception ex) {
+ throw new ImageCompressionException("Unable to load reference plane data.", ex);
+ }
Log(String.format("Training vector quantizer from reference plane %d.", options.getReferencePlaneIndex()));
final int[][] refPlaneVectors = getPlaneVectors(referencePlane);
@@ -101,9 +111,15 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
for (final int planeIndex : planeIndices) {
stopwatch.restart();
Log(String.format("Loading plane %d.", planeIndex));
- final ImageU16 plane = RawDataIO.loadImageU16(options.getInputFile(),
- options.getImageDimension(),
- planeIndex);
+
+ ImageU16 plane = null;
+ try {
+ plane = RawDataIO.loadImageU16(options.getInputFile(),
+ options.getImageDimension(),
+ planeIndex);
+ } catch (Exception ex) {
+ throw new ImageCompressionException("Unable to load plane data.", ex);
+ }
final int[][] planeVectors = getPlaneVectors(plane);
@@ -121,8 +137,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
try (OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048)) {
outBitStream.write(indices);
- } catch (IOException ioEx) {
- ioEx.printStackTrace();
+ } catch (Exception ex) {
+ throw new ImageCompressionException("Unable to write indices to OutBitStream.", ex);
}
stopwatch.stop();
Log("Plane time: " + stopwatch.getElapsedTimeString());
diff --git a/src/main/java/azgracompress/compression/VQImageDecompressor.java b/src/main/java/azgracompress/compression/VQImageDecompressor.java
index 2e27c317da6d3a0f61e16e8e916f04f82e2f63b1..1f77f7755a0d731e19640099b9e400d48cedbc78 100644
--- a/src/main/java/azgracompress/compression/VQImageDecompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageDecompressor.java
@@ -30,13 +30,17 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I
private int[][] readCodebookVectors(DataInputStream compressedStream,
final int codebookSize,
- final int vectorSize) throws IOException {
+ final int vectorSize) throws ImageDecompressionException {
int[][] codebook = new int[codebookSize][vectorSize];
- for (int codebookIndex = 0; codebookIndex < codebookSize; codebookIndex++) {
- for (int vecIndex = 0; vecIndex < vectorSize; vecIndex++) {
- codebook[codebookIndex][vecIndex] = compressedStream.readUnsignedShort();
+ try {
+ for (int codebookIndex = 0; codebookIndex < codebookSize; codebookIndex++) {
+ for (int vecIndex = 0; vecIndex < vectorSize; vecIndex++) {
+ codebook[codebookIndex][vecIndex] = compressedStream.readUnsignedShort();
+ }
}
+ } catch (IOException ioEx) {
+ throw new ImageDecompressionException("Unable to read quantization values from compressed stream.", ioEx);
}
return codebook;
}
@@ -87,7 +91,7 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I
@Override
public void decompress(DataInputStream compressedStream,
DataOutputStream decompressStream,
- QCMPFileHeader header) throws Exception {
+ QCMPFileHeader header) throws ImageDecompressionException {
final int codebookSize = (int) Math.pow(2, header.getBitsPerPixel());
assert (header.getVectorSizeZ() == 1);
final int vectorSize = header.getVectorSizeX() * header.getVectorSizeY() * header.getVectorSizeZ();
@@ -114,28 +118,43 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I
assert (quantizationVectors != null);
Log(String.format("Decompressing plane %d...", planeIndex));
- InBitStream inBitStream = new InBitStream(compressedStream, header.getBitsPerPixel(), (int) planeDataSize);
- inBitStream.readToBuffer();
- inBitStream.setAllowReadFromUnderlyingStream(false);
- final int[] indices = inBitStream.readNValues((int) planeVectorCount);
-
- int[][] decompressedVectors = new int[(int) planeVectorCount][vectorSize];
- for (int vecIndex = 0; vecIndex < planeVectorCount; vecIndex++) {
- System.arraycopy(quantizationVectors[indices[vecIndex]],
- 0,
- decompressedVectors[vecIndex],
- 0,
- vectorSize);
+
+ byte[] decompressedPlaneData = null;
+
+ try (InBitStream inBitStream = new InBitStream(compressedStream,
+ header.getBitsPerPixel(),
+ (int) planeDataSize)) {
+ inBitStream.readToBuffer();
+ inBitStream.setAllowReadFromUnderlyingStream(false);
+ final int[] indices = inBitStream.readNValues((int) planeVectorCount);
+
+ int[][] decompressedVectors = new int[(int) planeVectorCount][vectorSize];
+ for (int vecIndex = 0; vecIndex < planeVectorCount; vecIndex++) {
+
+ System.arraycopy(quantizationVectors[indices[vecIndex]],
+ 0,
+ decompressedVectors[vecIndex],
+ 0,
+ vectorSize);
+ }
+
+
+ final ImageU16 decompressedPlane = reconstructImageFromQuantizedVectors(decompressedVectors,
+ qVector,
+ header.getImageDims());
+ decompressedPlaneData =
+ TypeConverter.unsignedShortArrayToByteArray(decompressedPlane.getData(), false);
+ } catch (Exception ex) {
+ throw new ImageDecompressionException("Unable to read indices from InBitStream.", ex);
}
- final ImageU16 decompressedPlane = reconstructImageFromQuantizedVectors(decompressedVectors,
- qVector,
- header.getImageDims());
- final byte[] decompressedPlaneData = TypeConverter.unsignedShortArrayToByteArray(
- decompressedPlane.getData(),
- false);
- decompressStream.write(decompressedPlaneData);
+ try {
+ decompressStream.write(decompressedPlaneData);
+ } catch (IOException e) {
+ throw new ImageDecompressionException("Unable to write decompressed data to decompress stream.", e);
+ }
+
stopwatch.stop();
Log(String.format("Decompressed plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString()));
}
diff --git a/src/main/java/azgracompress/io/InBitStream.java b/src/main/java/azgracompress/io/InBitStream.java
index a104d85c7602a6c5326ffd41f251de03c2770db0..c64c120652212e616db550ab8db86df394e3dad7 100644
--- a/src/main/java/azgracompress/io/InBitStream.java
+++ b/src/main/java/azgracompress/io/InBitStream.java
@@ -3,7 +3,7 @@ package azgracompress.io;
import java.io.IOException;
import java.io.InputStream;
-public class InBitStream {
+public class InBitStream implements AutoCloseable {
private InputStream inputStream;
private byte[] buffer;
@@ -90,4 +90,9 @@ public class InBitStream {
}
+ @Override
+ public void close() throws Exception {
+ bitBufferSize = 0;
+ bytesAvailable = 0;
+ }
}
diff --git a/src/main/java/azgracompress/quantization/vector/LBGResult.java b/src/main/java/azgracompress/quantization/vector/LBGResult.java
index 57c290b173cd81198021f6743bf8a6f95b80dd94..6b751148f50689bd8efa273e850f4077a99516ee 100644
--- a/src/main/java/azgracompress/quantization/vector/LBGResult.java
+++ b/src/main/java/azgracompress/quantization/vector/LBGResult.java
@@ -1,6 +1,9 @@
package azgracompress.quantization.vector;
+import azgracompress.quantization.QTrainIteration;
+
public class LBGResult {
+
private final CodebookEntry[] codebook;
private final double averageMse;
private final double psnr;
diff --git a/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java b/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java
index d4391c2739d1dd4db40d49084c4cab0ae327ad11..13d009908ac2172ffd50148a10b767cee3cfbaf2 100644
--- a/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java
+++ b/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java
@@ -28,7 +28,6 @@ public class LBGVectorQuantizer {
return findOptimalCodebook(true);
}
- // TODO(Moravec): Maybe return QTrainIteration somehow?
public LBGResult findOptimalCodebook(boolean verbose) {
ArrayList<LearningCodebookEntry> codebook = initializeCodebook(verbose);
if (verbose) {
@@ -118,8 +117,6 @@ public class LBGVectorQuantizer {
// Create perturbation vector.
- // TODO(Moravec): Make sure that when we are splitting entry we don't end up creating two same entries.
- // The problem happens when we try to split Vector full of zeroes.
// Split each entry in codebook with fixed perturbation vector.
for (final LearningCodebookEntry entryToSplit : codebook) {
double[] prtV;
@@ -142,8 +139,8 @@ public class LBGVectorQuantizer {
newCodebook.add(entryToSplit);
ArrayList<Integer> rndEntryValues = new ArrayList<>(prtV.length);
- for (int j = 0; j < prtV.length; j++) {
- final int value = (int) Math.floor(prtV[j]);
+ for (final double v : prtV) {
+ final int value = (int) Math.floor(v);
assert (value >= 0) : "value is too low!";
assert (value <= U16.Max) : "value is too big!";
rndEntryValues.add(value);