diff --git a/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java b/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java
index 16562b64f6f06c7ced5a4b3207b7a584a55d94ee..7c01f3c2bb3e24007b3f7fe04235fd4926723d50 100644
--- a/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java
+++ b/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java
@@ -93,9 +93,7 @@ public class VectorQuantizationBenchmark extends BenchmarkBase {
 
         for (final int planeIndex : planes) {
             System.out.println(String.format("Loading plane %d ...", planeIndex));
-            // NOTE(Moravec): Actual planeIndex is zero based.
-
-            final ImageU16 plane = loadPlane(planeIndex - 1);
+            final ImageU16 plane = loadPlane(planeIndex);
 
             if (plane == null) {
                 System.err.println(String.format("Failed to load plane %d data. Skipping plane.", planeIndex));
diff --git a/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java b/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java
index 98dd5aba4aa13bdeb96f8bc3b6c4e51200131592..6ccf86eabe1bfb1321be9bda8af44b48e30f4cde 100644
--- a/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java
+++ b/src/main/java/azgracompress/quantization/vector/LBGVectorQuantizer.java
@@ -26,7 +26,7 @@ public class LBGVectorQuantizer {
 
         this.trainingVectors = new TrainingVector[vectors.length];
         for (int i = 0; i < vectors.length; i++) {
-            trainingVectors[i] = new TrainingVector(vectors[i]);
+            trainingVectors[i] = new TrainingVector(Arrays.copyOf(vectors[i], vectors[i].length));
         }
 
         this.vectorSize = vectors[0].length;
@@ -245,7 +245,7 @@ public class LBGVectorQuantizer {
                 }
 
                 // We always want to carry zero vector to next iteration.
-                if (isZeroVector(entryToSplit.getVector())) {
+                if (VectorQuantizer.isZeroVector(entryToSplit.getVector())) {
                     // Use zero vector in next iteration.
                     newCodebook[cbIndex++] = entryToSplit;
 
@@ -261,7 +261,7 @@ public class LBGVectorQuantizer {
                     continue;
                 }
 
-                if (isZeroVector(prtV)) {
+                if (VectorQuantizer.isZeroVector(prtV)) {
                     // Zero perturbation vector can't create two different entries.
                     // The original entry is going to be moved to the next codebook with the new
                     // random entry, which will get improved in the LBG algorithm.
@@ -321,36 +321,6 @@ public class LBGVectorQuantizer {
         return randomVector;
     }
 
-    /**
-     * Check whether all vector elements are equal to 0.0
-     *
-     * @param vector Vector array.
-     * @return True if all elements are zeros.
-     */
-    private boolean isZeroVector(final double[] vector) {
-        for (final double value : vector) {
-            if (value != 0.0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Check whether all vector elements are equal to 0
-     *
-     * @param vector Vector array.
-     * @return True if all elements are zeros.
-     */
-    private boolean isZeroVector(final int[] vector) {
-        for (final double value : vector) {
-            if (value != 0.0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
 
     /**
      * Execute the LBG algorithm with default epsilon value.
@@ -657,7 +627,9 @@ public class LBGVectorQuantizer {
         int largestEntrySize = codebook[emptyEntryIndex].getVectorCount();
         // NOTE(Moravec): We can't select random training vector, because zero vector would create another zero vector.
         for (int i = 0; i < codebook.length; i++) {
-            if ((codebook[i].getVectorCount() > largestEntrySize) && !isZeroVector(codebook[i].getVector())) {
+            if ((codebook[i].getVectorCount() > largestEntrySize) &&
+                    !VectorQuantizer.isZeroVector(codebook[i].getVector())) {
+
                 largestEntryIndex = i;
                 largestEntrySize = codebook[i].getVectorCount();
             }
diff --git a/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java b/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java
index 22ad150878129f640cdb7f9d1e4ba168d559472d..44318aa45c6055da8a5368cbbbe85c34159ae3ea 100644
--- a/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java
+++ b/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java
@@ -2,6 +2,7 @@ package azgracompress.quantization.vector;
 
 public class VectorQuantizer {
 
+    private final VectorDistanceMetric metric = VectorDistanceMetric.Euclidean;
     private final CodebookEntry[] codebook;
     private final int vectorSize;
 
@@ -12,7 +13,7 @@ public class VectorQuantizer {
 
     public int[] quantize(final int[] dataVector) {
         assert (dataVector.length > 0 && dataVector.length % vectorSize == 0) : "Wrong vector size";
-        final CodebookEntry closestEntry = findClosestCodebookEntry(dataVector, VectorDistanceMetric.Euclidean);
+        final CodebookEntry closestEntry = findClosestCodebookEntry(dataVector, metric);
         return closestEntry.getVector();
     }
 
@@ -22,8 +23,7 @@ public class VectorQuantizer {
 
         if (workerCount == 1) {
             for (int vectorIndex = 0; vectorIndex < dataVectors.length; vectorIndex++) {
-                final CodebookEntry closestEntry = findClosestCodebookEntry(dataVectors[vectorIndex],
-                                                                            VectorDistanceMetric.Euclidean);
+                final CodebookEntry closestEntry = findClosestCodebookEntry(dataVectors[vectorIndex], metric);
                 result[vectorIndex] = closestEntry.getVector();
             }
         } else {
@@ -48,8 +48,7 @@ public class VectorQuantizer {
 
         if (maxWorkerCount == 1) {
             for (int vectorIndex = 0; vectorIndex < dataVectors.length; vectorIndex++) {
-                indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex],
-                                                                     VectorDistanceMetric.Euclidean);
+                indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex], metric);
             }
         } else {
             // Cap the worker count on 8
@@ -63,8 +62,7 @@ public class VectorQuantizer {
 
                 workers[wId] = new Thread(() -> {
                     for (int vectorIndex = fromIndex; vectorIndex < toIndex; vectorIndex++) {
-                        indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex],
-                                                                             VectorDistanceMetric.Euclidean);
+                        indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex], metric);
                     }
                 });
 
@@ -117,7 +115,7 @@ public class VectorQuantizer {
     }
 
     private CodebookEntry findClosestCodebookEntry(final int[] dataVector) {
-        return findClosestCodebookEntry(dataVector, VectorDistanceMetric.Euclidean);
+        return findClosestCodebookEntry(dataVector, metric);
     }
 
     private CodebookEntry findClosestCodebookEntry(final int[] dataVector, final VectorDistanceMetric metric) {
@@ -125,21 +123,58 @@ public class VectorQuantizer {
     }
 
     private int findClosestCodebookEntryIndex(final int[] dataVector, final VectorDistanceMetric metric) {
+        boolean closesIsZero = false;
         double minDist = Double.MAX_VALUE;
         int closestEntryIndex = 0;
-        final int codebookSize = codebook.length;
-        for (int i = 0; i < codebookSize; i++) {
-            final double dist = distanceBetweenVectors(dataVector, codebook[i].getVector(), metric);
+        for (int entryIndex = 0; entryIndex < codebook.length; entryIndex++) {
+
+
+            final double dist = distanceBetweenVectors(dataVector, codebook[entryIndex].getVector(), metric);
             if (dist < minDist) {
                 minDist = dist;
-                closestEntryIndex = i;
+                closestEntryIndex = entryIndex;
+                closesIsZero = isZeroVector(codebook[entryIndex].getVector());
             }
         }
+
+        if (closesIsZero) {
+//            System.out.println("One of zero vectors.");
+        }
         return closestEntryIndex;
     }
 
     public CodebookEntry[] getCodebook() {
         return codebook;
     }
+
+    /**
+     * Check whether all vector elements are equal to 0.0
+     *
+     * @param vector Vector array.
+     * @return True if all elements are zeros.
+     */
+    public static boolean isZeroVector(final double[] vector) {
+        for (final double value : vector) {
+            if (value != 0.0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check whether all vector elements are equal to 0
+     *
+     * @param vector Vector array.
+     * @return True if all elements are zeros.
+     */
+    public static boolean isZeroVector(final int[] vector) {
+        for (final double value : vector) {
+            if (value != 0.0) {
+                return false;
+            }
+        }
+        return true;
+    }
 }