diff --git a/src/main/java/azgracompress/benchmark/VQBenchmark.java b/src/main/java/azgracompress/benchmark/VQBenchmark.java
index 3161f1a04876d654fc6555a9676cecd4a15a36c9..366dfbffd78976f657eeb2598e3828e5998b3b88 100644
--- a/src/main/java/azgracompress/benchmark/VQBenchmark.java
+++ b/src/main/java/azgracompress/benchmark/VQBenchmark.java
@@ -1,36 +1,23 @@
 package azgracompress.benchmark;
 
-import azgracompress.U16;
-import azgracompress.cache.QuantizationCacheManager;
 import azgracompress.cli.ParsedCliOptions;
-import azgracompress.compression.CompressionOptions;
-import azgracompress.data.*;
-import azgracompress.io.loader.IPlaneLoader;
-import azgracompress.io.loader.PlaneLoaderFactory;
-import azgracompress.quantization.vector.LBGResult;
-import azgracompress.quantization.vector.LBGVectorQuantizer;
-import azgracompress.quantization.vector.VQCodebook;
-import azgracompress.quantization.vector.VectorQuantizer;
-import azgracompress.utilities.Utils;
-
-import java.io.File;
-import java.io.IOException;
+import azgracompress.data.Chunk2D;
+import azgracompress.data.ImageU16;
+import azgracompress.data.V2i;
+import azgracompress.data.V3i;
 
 public class VQBenchmark extends BenchmarkBase {
 
-    final static V2i DEFAULT_QVECTOR = new V2i(3, 3);
-
     public VQBenchmark(final ParsedCliOptions options) {
         super(options);
     }
 
     @Override
     public void startBenchmark() {
-        startBenchmark(DEFAULT_QVECTOR);
+        startBenchmark(options.getQuantizationVector());
     }
 
-    private ImageU16 reconstructImageFromQuantizedVectors(final ImageU16 plane,
-                                                          final int[][] vectors,
+    private ImageU16 reconstructImageFromQuantizedVectors(final int[][] vectors,
                                                           final V2i qVector) {
         Chunk2D reconstructedChunk = new Chunk2D(new V2i(rawImageDims.getX(), rawImageDims.getY()));
         if (qVector.getY() > 1) {
@@ -42,111 +29,98 @@ public class VQBenchmark extends BenchmarkBase {
         return reconstructedChunk.asImageU16();
     }
 
-    private int[][] getPlaneVectors(final ImageU16 plane, final V2i qVector) {
-        return plane.toQuantizationVectors(qVector);
-    }
-
-    public void startBenchmark(final V2i qVector) {
-        if (planes.length < 1) {
-            return;
-        }
-        IPlaneLoader planeLoader;
-        try {
-            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(options.getInputDataInfo());
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.err.println("Unable to create SCIFIO reader.");
-            return;
-        }
-        if (qVector.getY() > 1) {
-            System.out.println("2D qVector");
-        } else {
-            System.out.println("1D qVector");
-        }
-        boolean dirCreated = new File(this.outputDirectory).mkdirs();
-        System.out.println(String.format("|CODEBOOK| = %d", codebookSize));
-        VectorQuantizer quantizer = null;
-
-        if (options.getCodebookType() == CompressionOptions.CodebookType.Global) {
-            System.out.println("Loading codebook from cache");
-            QuantizationCacheManager cacheManager = new QuantizationCacheManager(cacheFolder);
-            final VQCodebook codebook = cacheManager.loadVQCodebook(inputFile, codebookSize, qVector.toV3i());
-            if (codebook == null) {
-                System.err.println("Failed to read quantization vectors from cache.");
-                return;
-            }
-            quantizer = new VectorQuantizer(codebook);
-            System.out.println("Created quantizer from cache");
-
-        } else if (options.getCodebookType() == CompressionOptions.CodebookType.MiddlePlane) {
-            final int middlePlaneIndex = rawImageDims.getZ() / 2;
-            final ImageU16 middlePlane;
-            try {
-
-                middlePlane = new ImageU16(options.getInputDataInfo().getDimensions().toV2i(), planeLoader.loadPlaneData(middlePlaneIndex));
-            } catch (IOException e) {
-                e.printStackTrace();
-                System.err.println("Failed to load middle plane data.");
-                return;
-            }
-
-            final int[][] refPlaneData = getPlaneVectors(middlePlane, qVector);
-            LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(refPlaneData,
-                                                                      codebookSize,
-                                                                      workerCount,
-                                                                      qVector.toV3i());
-            final LBGResult vqResult = vqInitializer.findOptimalCodebook();
-            quantizer = new VectorQuantizer(vqResult.getCodebook());
-            System.out.println("Created quantizer from middle plane.");
-        }
-
-        for (final int planeIndex : planes) {
-            System.out.println(String.format("Loading plane %d ...", planeIndex));
-
-            final ImageU16 plane;
-            try {
-                plane = new ImageU16(options.getInputDataInfo().getDimensions().toV2i(), planeLoader.loadPlaneData(planeIndex));
-            } catch (IOException e) {
-                e.printStackTrace();
-                System.err.println(String.format("Failed to load plane %d data. Skipping plane.", planeIndex));
-                return;
-            }
-
-            final int[][] planeData = getPlaneVectors(plane, qVector);
-
-
-            if (options.getCodebookType() == CompressionOptions.CodebookType.Individual) {
-                LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(planeData,
-                                                                          codebookSize,
-                                                                          workerCount,
-                                                                          qVector.toV3i());
-                LBGResult vqResult = vqInitializer.findOptimalCodebook();
-                quantizer = new VectorQuantizer(vqResult.getCodebook());
-                System.out.println("Created plane quantizer.");
-            }
-
-            final String quantizedFile = String.format(QUANTIZED_FILE_TEMPLATE, planeIndex, codebookSize);
-            final String diffFile = String.format(DIFFERENCE_FILE_TEMPLATE, planeIndex, codebookSize);
-            final String absoluteDiffFile = String.format(ABSOLUTE_DIFFERENCE_FILE_TEMPLATE,
-                                                          planeIndex,
-                                                          codebookSize);
-
-            final int[][] quantizedData = quantizer.quantize(planeData, workerCount);
-
-            final ImageU16 quantizedImage = reconstructImageFromQuantizedVectors(plane, quantizedData, qVector);
-
-
-            final int[] diffArray = Utils.getDifference(plane.getData(), quantizedImage.getData());
-            final double mse = Utils.calculateMse(diffArray);
-            final double PSNR = Utils.calculatePsnr(mse, U16.Max);
-            System.out.println(String.format("MSE: %.4f\tPSNR: %.4f(dB)", mse, PSNR));
-
-            if (!saveQuantizedPlaneData(quantizedImage.getData(), quantizedFile)) {
-                System.err.println("Failed to save quantized plane.");
-                return;
-            }
-
-            saveDifference(diffArray, diffFile, absoluteDiffFile);
-        }
+    public void startBenchmark(final V3i qVector) {
+        // NOTE(Moravec): This will be enabled once we need to benchmark something.
+        //        if (planes.length < 1) {
+        //            return;
+        //        }
+        //        IPlaneLoader planeLoader;
+        //        try {
+        //            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(options.getInputDataInfo());
+        //        } catch (Exception e) {
+        //            e.printStackTrace();
+        //            System.err.println("Unable to create specific reader.");
+        //            return;
+        //        }
+        //        if (qVector.getY() > 1) {
+        //            System.out.println("2D qVector");
+        //        } else {
+        //            System.out.println("1D qVector");
+        //        }
+        //        boolean dirCreated = new File(this.outputDirectory).mkdirs();
+        //        System.out.printf("|CODEBOOK| = %d%n", codebookSize);
+        //        VectorQuantizer quantizer = null;
+        //
+        //        if (options.getCodebookType() == CompressionOptions.CodebookType.Global) {
+        //            System.out.println("Loading codebook from cache");
+        //            QuantizationCacheManager cacheManager = new QuantizationCacheManager(cacheFolder);
+        //            final VQCodebook codebook = cacheManager.loadVQCodebook(inputFile, codebookSize, qVector);
+        //            if (codebook == null) {
+        //                System.err.println("Failed to read quantization vectors from cache.");
+        //                return;
+        //            }
+        //            quantizer = new VectorQuantizer(codebook);
+        //            System.out.println("Created quantizer from cache");
+        //
+        //        } else if (options.getCodebookType() == CompressionOptions.CodebookType.MiddlePlane) {
+        //            final int middlePlaneIndex = rawImageDims.getZ() / 2;
+        //            int[][] refPlaneData;
+        //            try {
+        //                refPlaneData = planeLoader.loadVectorsFromPlaneRange(options, Utils.singlePlaneRange(middlePlaneIndex));
+        //            } catch (ImageCompressionException e) {
+        //                e.printStackTrace();
+        //                System.err.println("Failed to load middle plane data.");
+        //                return;
+        //            }
+        //
+        //            LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(refPlaneData, codebookSize, workerCount, qVector);
+        //            final LBGResult vqResult = vqInitializer.findOptimalCodebook();
+        //
+        //            quantizer = new VectorQuantizer(vqResult.getCodebook());
+        //            System.out.println("Created quantizer from middle plane.");
+        //        }
+        //
+        //        for (final int planeIndex : planes) {
+        //            System.out.printf("Loading plane %d ...%n", planeIndex);
+        //
+        //            int[][] planeData;
+        //            try {
+        //                planeData = planeLoader.loadVectorsFromPlaneRange(options, Utils.singlePlaneRange(planeIndex));
+        //            } catch (ImageCompressionException e) {
+        //                e.printStackTrace();
+        //                System.err.printf("Failed to load plane %d data.", planeIndex);
+        //                return;
+        //            }
+        //
+        //
+        //            if (options.getCodebookType() == CompressionOptions.CodebookType.Individual) {
+        //                LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(planeData, codebookSize, workerCount, qVector);
+        //                LBGResult vqResult = vqInitializer.findOptimalCodebook();
+        //                quantizer = new VectorQuantizer(vqResult.getCodebook());
+        //                System.out.println("Created plane quantizer.");
+        //            }
+        //
+        //            final String quantizedFile = String.format(QUANTIZED_FILE_TEMPLATE, planeIndex, codebookSize);
+        //            final String diffFile = String.format(DIFFERENCE_FILE_TEMPLATE, planeIndex, codebookSize);
+        //            final String absoluteDiffFile = String.format(ABSOLUTE_DIFFERENCE_FILE_TEMPLATE, planeIndex, codebookSize);
+        //
+        //            assert (quantizer != null);
+        //            final int[][] quantizedData = quantizer.quantize(planeData, workerCount);
+        //
+        //            final ImageU16 quantizedImage = reconstructImageFromQuantizedVectors(quantizedData, qVector.toV2i());
+        //
+        //
+        //            final int[] diffArray = Utils.getDifference(plane.getData(), quantizedImage.getData());
+        //            final double mse = Utils.calculateMse(diffArray);
+        //            final double PSNR = Utils.calculatePsnr(mse, U16.Max);
+        //            System.out.printf("MSE: %.4f\tPSNR: %.4f(dB)%n", mse, PSNR);
+        //
+        //            if (!saveQuantizedPlaneData(quantizedImage.getData(), quantizedFile)) {
+        //                System.err.println("Failed to save quantized plane.");
+        //                return;
+        //            }
+        //
+        //            saveDifference(diffArray, diffFile, absoluteDiffFile);
+        //        }
     }
 }
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
index 976f40fcc4fd37d9ec9acbd768c7529381b43748..777236c62124b0165b2b4988b15a4fb59559b516 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -2,8 +2,6 @@ package azgracompress.compression;
 
 import azgracompress.cache.QuantizationCacheManager;
 import azgracompress.compression.exception.ImageCompressionException;
-import azgracompress.data.Chunk2D;
-import azgracompress.data.ImageU16;
 import azgracompress.data.Range;
 import azgracompress.fileformat.QuantizationType;
 import azgracompress.huffman.Huffman;
@@ -12,6 +10,7 @@ import azgracompress.io.loader.IPlaneLoader;
 import azgracompress.io.loader.PlaneLoaderFactory;
 import azgracompress.quantization.vector.*;
 import azgracompress.utilities.Stopwatch;
+import azgracompress.utilities.Utils;
 import org.jetbrains.annotations.NotNull;
 
 import java.io.DataOutputStream;
@@ -32,9 +31,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
     private VectorQuantizer trainVectorQuantizerFromPlaneVectors(final int[][] planeVectors) {
 
         LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(planeVectors,
-                getCodebookSize(),
-                options.getWorkerCount(),
-                options.getQuantizationVector());
+                                                                  getCodebookSize(),
+                                                                  options.getWorkerCount(),
+                                                                  options.getQuantizationVector());
         LBGResult vqResult = vqInitializer.findOptimalCodebook();
         return new VectorQuantizer(vqResult.getCodebook());
     }
@@ -79,14 +78,14 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
         QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder());
 
         if (!cacheManager.doesVQCacheExists(options.getInputDataInfo().getCacheFileName(),
-                getCodebookSize(),
-                options.getQuantizationVector())) {
+                                            getCodebookSize(),
+                                            options.getQuantizationVector())) {
             trainAndSaveCodebook();
         }
 
         final VQCodebook codebook = cacheManager.loadVQCodebook(options.getInputDataInfo().getCacheFileName(),
-                getCodebookSize(),
-                options.getQuantizationVector());
+                                                                getCodebookSize(),
+                                                                options.getQuantizationVector());
 
         if (codebook == null) {
             throw new ImageCompressionException("Failed to read quantization vectors from cache.");
@@ -132,17 +131,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
             writeQuantizerToCompressStream(quantizer, compressStream);
         } else if (options.getCodebookType() == CompressionOptions.CodebookType.MiddlePlane) {
             stopwatch.restart();
-
-            final int middlePlaneIndex = getMiddlePlaneIndex();
-            ImageU16 middlePlane = null;
-            try {
-                middlePlane = new ImageU16(options.getInputDataInfo().getDimensions().toV2i(), planeLoader.loadPlaneData(middlePlaneIndex));
-            } catch (IOException ex) {
-                throw new ImageCompressionException("Unable to load reference plane data.", ex);
-            }
-
-            reportStatusToListeners(String.format("Training vector quantizer from middle plane %d.", middlePlaneIndex));
-            final int[][] refPlaneVectors = middlePlane.toQuantizationVectors(options.getQuantizationVector().toV2i());
+            reportStatusToListeners("Training vector quantizer from middle plane.");
+            final int[][] refPlaneVectors = planeLoader.loadVectorsFromPlaneRange(options, Utils.singlePlaneRange(getMiddlePlaneIndex()));
             quantizer = trainVectorQuantizerFromPlaneVectors(refPlaneVectors);
             huffman = createHuffmanCoder(huffmanSymbols, quantizer.getFrequencies());
             writeQuantizerToCompressStream(quantizer, compressStream);
@@ -158,14 +148,7 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
             stopwatch.restart();
             reportStatusToListeners(String.format("Loading plane %d.", planeIndex));
 
-            ImageU16 plane = null;
-            try {
-                plane = new ImageU16(options.getInputDataInfo().getDimensions().toV2i(), planeLoader.loadPlaneData(planeIndex));
-            } catch (IOException ex) {
-                throw new ImageCompressionException("Unable to load plane data.", ex);
-            }
-
-            final int[][] planeVectors = plane.toQuantizationVectors(options.getQuantizationVector().toV2i());
+            final int[][] planeVectors = planeLoader.loadVectorsFromPlaneRange(options, Utils.singlePlaneRange(planeIndex));
 
             if (!hasGeneralQuantizer) {
                 reportStatusToListeners(String.format("Training vector quantizer from plane %d.", planeIndex));
@@ -182,99 +165,41 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
 
             stopwatch.stop();
             reportProgressToListeners(planeIndex, planeIndices.length,
-                    "Finished compression of plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString());
+                                      "Finished compression of plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString());
         }
         return planeDataSizes;
     }
 
-
-    /**
-     * Load plane and convert the plane into quantization vectors.
-     *
-     * @param planeIndex Zero based plane index.
-     * @return Quantization vectors of configured quantization.
-     * @throws IOException When reading fails.
-     */
-
-    private int[][] loadPlaneQuantizationVectors(final IPlaneLoader planeLoader,
-                                                 final int planeIndex) throws IOException {
-        ImageU16 refPlane = new ImageU16(options.getInputDataInfo().getDimensions().toV2i(), planeLoader.loadPlaneData(planeIndex));
-        return refPlane.toQuantizationVectors(options.getQuantizationVector().toV2i());
-    }
-
-    private int[][] loadConfiguredPlanesData() throws ImageCompressionException {
+    @Override
+    public void trainAndSaveCodebook() throws ImageCompressionException {
+        reportStatusToListeners("Loading image data...");
 
         final IPlaneLoader planeLoader;
         try {
             planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(options.getInputDataInfo());
-            planeLoader.setWorkerCount(options.getWorkerCount());
         } catch (Exception e) {
-            throw new ImageCompressionException("Unable to create reader. " + e.getMessage());
+            throw new ImageCompressionException("Unable to create plane reader. " + e.getMessage());
         }
-        if (options.getQuantizationType().isOneOf(QuantizationType.Vector1D, QuantizationType.Vector2D)) {
-            // TODO: Chunk2D operations should eventually be moved to loaders.
-            //  Same as voxel loading, so that we wouldn't have to copy data twice.
-            final int vectorSize = options.getQuantizationVector().toV2i().multiplyTogether();
-
-            int[][] trainData;
-            Stopwatch s = Stopwatch.startNew();
-            if (options.getInputDataInfo().isPlaneIndexSet()) {
-                reportStatusToListeners("VQ: Loading single plane data.");
-                try {
-                    trainData = loadPlaneQuantizationVectors(planeLoader, options.getInputDataInfo().getPlaneIndex());
-                } catch (IOException e) {
-                    throw new ImageCompressionException("Failed to load plane data.", e);
-                }
-            } else {
-                reportStatusToListeners(options.getInputDataInfo().isPlaneRangeSet() ?
-                        "VQ: Loading plane range data." : "VQ: Loading all planes data.");
-
-                final int[] planeIndices = getPlaneIndicesForCompression();
-                final int chunkCountPerPlane = Chunk2D.calculateRequiredChunkCount(options.getInputDataInfo().getDimensions().toV2i(),
-                        options.getQuantizationVector().toV2i());
-                final int totalChunkCount = chunkCountPerPlane * planeIndices.length;
-                trainData = new int[totalChunkCount][vectorSize];
-
-                int[][] planeVectors;
-                int planeCounter = 0;
-                for (final int planeIndex : planeIndices) {
-                    try {
-                        planeVectors = loadPlaneQuantizationVectors(planeLoader, planeIndex);
-                        assert (planeVectors.length == chunkCountPerPlane) : "Wrong chunk count per plane";
-                    } catch (IOException e) {
-                        throw new ImageCompressionException(String.format("Failed to load plane %d image data.", planeIndex), e);
-                    }
-
-                    System.arraycopy(planeVectors, 0, trainData, (planeCounter * chunkCountPerPlane), chunkCountPerPlane);
-                    ++planeCounter;
-                }
-            }
-            s.stop();
-            reportStatusToListeners("Quantization vector load took: " + s.getElapsedTimeString());
-            return trainData;
-        } else {
-            if (options.getQuantizationType() != QuantizationType.Vector3D) {
-                throw new ImageCompressionException("Invalid QuantizationType, expected: `QuantizationType.Vector3D`, but got: " +
-                        options.getQuantizationType().toString());
-            }
 
-            try {
-                return planeLoader.loadVoxels(options.getQuantizationVector());
-            } catch (IOException e) {
-                throw new ImageCompressionException("Unable to load voxels.", e);
-            }
+        int[][] trainingData;
+        if (options.getInputDataInfo().isPlaneIndexSet()) {
+            reportStatusToListeners("VQ: Loading single plane data.");
+            final int planeIndex = options.getInputDataInfo().getPlaneIndex();
+            trainingData = planeLoader.loadVectorsFromPlaneRange(options, new Range<>(planeIndex, planeIndex + 1));
+        } else if (options.getInputDataInfo().isPlaneRangeSet()) {
+            reportStatusToListeners("VQ: Loading plane range data.");
+            trainingData = planeLoader.loadVectorsFromPlaneRange(options, options.getInputDataInfo().getPlaneRange());
+        } else {
+            reportStatusToListeners("VQ: Loading all planes data.");
+            trainingData = planeLoader.loadVectorsFromPlaneRange(options,
+                                                                 new Range<>(0, options.getInputDataInfo().getDimensions().getZ()));
         }
-    }
 
-    @Override
-    public void trainAndSaveCodebook() throws ImageCompressionException {
-        reportStatusToListeners("Loading image data...");
-        final int[][] trainingData = loadConfiguredPlanesData();
 
         LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(trainingData,
-                getCodebookSize(),
-                options.getWorkerCount(),
-                options.getQuantizationVector());
+                                                                  getCodebookSize(),
+                                                                  options.getWorkerCount(),
+                                                                  options.getQuantizationVector());
 
         reportStatusToListeners("Starting LBG optimization.");
         vqInitializer.setStatusListener(this::reportStatusToListeners);
@@ -348,8 +273,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
             voxelLayersSizes[voxelLayerIndex] = writeHuffmanEncodedIndices(compressStream, huffman, indices);
             stopwatch.stop();
             reportProgressToListeners(voxelLayerIndex, voxelLayerCount,
-                    "%d/%d Finished voxel layer %s compression pass in %s",
-                    voxelLayerIndex, voxelLayerCount, voxelLayerRange.toString(), stopwatch.getElapsedTimeString());
+                                      "%d/%d Finished voxel layer %s compression pass in %s",
+                                      voxelLayerIndex, voxelLayerCount, voxelLayerRange.toString(), stopwatch.getElapsedTimeString());
         }
 
         return voxelLayersSizes;
diff --git a/src/main/java/azgracompress/data/Chunk2D.java b/src/main/java/azgracompress/data/Chunk2D.java
index 1f337dee9e7b71647c417170848cbd3026b1473c..3e4664d1a6f90bac52229a187504ffa96a33dbab 100644
--- a/src/main/java/azgracompress/data/Chunk2D.java
+++ b/src/main/java/azgracompress/data/Chunk2D.java
@@ -70,32 +70,6 @@ public class Chunk2D {
         return String.format("2D shape %s %d values", dims.toString(), data.length);
     }
 
-    /**
-     * Divide this Chunk to 1D row vector of given length.
-     *
-     * @param vectorSize Vector length.
-     * @return Array of row vectors.
-     */
-    public int[][] divideInto1DVectors(final int vectorSize) {
-        final int rowVectorCount = (int) Math.ceil(dims.getX() / (float) vectorSize);
-        final int vectorCount = rowVectorCount * dims.getY();
-        int[][] imageVectors = new int[vectorCount][vectorSize];
-
-        int vec = 0;
-        int srcX;
-        for (int row = 0; row < dims.getY(); row++) {
-            for (int vecIndex = 0; vecIndex < rowVectorCount; vecIndex++) {
-                for (int x = 0; x < vectorSize; x++) {
-                    srcX = (vecIndex * vectorSize) + x;
-                    imageVectors[vec][x] = isInside(srcX, row) ? data[index(srcX, row)] : FILL_VALUE;
-                }
-                ++vec;
-            }
-        }
-
-        return imageVectors;
-    }
-
     /**
      * Reconstruct this Chunk from array of 1D row vectors.
      *
@@ -125,27 +99,6 @@ public class Chunk2D {
         }
     }
 
-    /**
-     * Divide this Chunk to 2D matrices of given dimensions.
-     *
-     * @param qVectorDims Matrix dimension.
-     * @return Array of matrix data.
-     */
-    public int[][] divideInto2DVectors(final V2i qVectorDims) {
-        final int chunkSize = qVectorDims.getX() * qVectorDims.getY();
-        final int chunkCount = calculateRequiredChunkCount(qVectorDims);
-
-        int[][] vectors = new int[chunkCount][chunkSize];
-        int vecIndex = 0;
-
-        for (int chunkYOffset = 0; chunkYOffset < dims.getY(); chunkYOffset += qVectorDims.getY()) {
-            for (int chunkXOffset = 0; chunkXOffset < dims.getX(); chunkXOffset += qVectorDims.getX()) {
-                copyDataToVector(vectors[vecIndex++], qVectorDims, chunkXOffset, chunkYOffset);
-            }
-        }
-        return vectors;
-    }
-
     /**
      * Reconstruct this Chunk (copy data) from matrix vectors.
      *
@@ -169,17 +122,6 @@ public class Chunk2D {
         assert (vecIndex == vectors.length);
     }
 
-
-    /**
-     * Calculate the number of required 2D matrices for plane.
-     *
-     * @param chunkDims Matrix dimension.
-     * @return Number of required chunks.
-     */
-    private int calculateRequiredChunkCount(final V2i chunkDims) {
-        return calculateRequiredChunkCount(dims, chunkDims);
-    }
-
     /**
      * Calculate the number of required 2D matrices for plane of given dimensions.
      *
@@ -205,26 +147,6 @@ public class Chunk2D {
         return (((x >= 0) && (x < dims.getX())) && (y >= 0) && (y < dims.getY()));
     }
 
-    /**
-     * Copy this chunk data to chunk vector.
-     *
-     * @param vector       Chunk vector.
-     * @param qVectorDims  Dimensions of the vector.
-     * @param chunkXOffset Chunk X offset
-     * @param chunkYOffset Chunk Y offset.
-     */
-    private void copyDataToVector(int[] vector, final V2i qVectorDims, final int chunkXOffset, final int chunkYOffset) {
-        int srcX, srcY;
-        for (int y = 0; y < qVectorDims.getY(); y++) {
-            srcY = chunkYOffset + y;
-            for (int x = 0; x < qVectorDims.getX(); x++) {
-                srcX = chunkXOffset + x;
-                final int dstIndex = index(x, y, qVectorDims.getY());
-                vector[dstIndex] = isInside(srcX, srcY) ? data[index(srcX, srcY)] : FILL_VALUE;
-            }
-        }
-    }
-
     /**
      * Copy data from chunk vector to this chunk.
      *
diff --git a/src/main/java/azgracompress/data/ImageU16.java b/src/main/java/azgracompress/data/ImageU16.java
index 65e9afbff0f1dcbaa8bef18845520e2382600a06..589ee1e7fe5dede51e9c9a17aee31579bb0318e8 100644
--- a/src/main/java/azgracompress/data/ImageU16.java
+++ b/src/main/java/azgracompress/data/ImageU16.java
@@ -54,20 +54,20 @@ public class ImageU16 {
         return height;
     }
 
-    /**
-     * Chunk the image data into quantization vectors of requested dimension.
-     *
-     * @param qVectorDims Quantization vector dimension.
-     * @return Array of quantization vectors.
-     */
-    public int[][] toQuantizationVectors(final V2i qVectorDims) {
-        if (qVectorDims.getY() == 1) {
-            // 1D row vectors.
-            return as2dChunk().divideInto1DVectors(qVectorDims.getX());
-        } else {
-            // 2D matrix vectors.
-            return as2dChunk().divideInto2DVectors(qVectorDims);
-            //return Chunk2D.chunksAsImageVectors(as2dChunk().divideIntoChunks(qVectorDims));
-        }
-    }
+//    /**
+//     * Chunk the image data into quantization vectors of requested dimension.
+//     *
+//     * @param qVectorDims Quantization vector dimension.
+//     * @return Array of quantization vectors.
+//     */
+//    public int[][] toQuantizationVectors(final V2i qVectorDims) {
+//        if (qVectorDims.getY() == 1) {
+//            // 1D row vectors.
+//            return as2dChunk().divideInto1DVectors(qVectorDims.getX());
+//        } else {
+//            // 2D matrix vectors.
+//            return as2dChunk().divideInto2DVectors(qVectorDims);
+//            //return Chunk2D.chunksAsImageVectors(as2dChunk().divideIntoChunks(qVectorDims));
+//        }
+//    }
 }
diff --git a/src/main/java/azgracompress/io/loader/IPlaneLoader.java b/src/main/java/azgracompress/io/loader/IPlaneLoader.java
index db338cf36b6dffa12b8b59b228e0ac968495f555..e88a46951b7a69106d93b37c5f77c4ee8a57c359 100644
--- a/src/main/java/azgracompress/io/loader/IPlaneLoader.java
+++ b/src/main/java/azgracompress/io/loader/IPlaneLoader.java
@@ -1,5 +1,7 @@
 package azgracompress.io.loader;
 
+import azgracompress.compression.CompressionOptions;
+import azgracompress.compression.exception.ImageCompressionException;
 import azgracompress.data.Range;
 import azgracompress.data.V2i;
 import azgracompress.data.V3i;
@@ -124,4 +126,33 @@ public interface IPlaneLoader {
      * @param threadCount Available thread count for loader.
      */
     void setWorkerCount(final int threadCount);
+
+    /**
+     * Load correct type of vectors (quantization type in options) from specified plane range.
+     *
+     * @param planeRange Plane range to load vectors from.
+     * @return Vector data from plane range.
+     * @throws ImageCompressionException When fails to load plane range.
+     */
+    default int[][] loadVectorsFromPlaneRange(final CompressionOptions options,
+                                              final Range<Integer> planeRange) throws ImageCompressionException {
+
+        setWorkerCount(supportParallelLoading() ? options.getWorkerCount() : 1);
+
+        try {
+            switch (options.getQuantizationType()) {
+                case Vector1D:
+                    return loadRowVectors(options.getQuantizationVector().getX(), planeRange);
+                case Vector2D:
+                    return loadBlocks(options.getQuantizationVector().toV2i(), planeRange);
+                case Vector3D:
+                    return loadVoxels(options.getQuantizationVector(), planeRange);
+                default: {
+                    throw new ImageCompressionException("Invalid QuantizationType '" + options.getQuantizationType().toString() + "'");
+                }
+            }
+        } catch (IOException e) {
+            throw new ImageCompressionException("Unable to load vectors QuantizationType=" + options.getQuantizationType(), e);
+        }
+    }
 }
diff --git a/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java b/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
index b147eba2f70b90f52a7de6dd42344c557e407dfe..6783ba6959acc41f7844c342e68fc44d746c8c40 100644
--- a/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
+++ b/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
@@ -18,7 +18,7 @@ public final class PlaneLoaderFactory {
             case RawDataLoader:
                 return new RawDataLoader((FileInputData) inputDataInfo);
             case SCIFIOLoader:
-                return new SCIFIOLoader((FileInputData)inputDataInfo);
+                return new SCIFIOLoader((FileInputData) inputDataInfo);
             case ImageJBufferLoader:
                 return new ImageJBufferLoader((BufferInputData) inputDataInfo);
             default:
diff --git a/src/main/java/azgracompress/utilities/Utils.java b/src/main/java/azgracompress/utilities/Utils.java
index 9d7a773d9b7feb2913f3ffd640f17b7c5964660a..008f6509b0e7e8ddaefa1851c11ddd424a8254eb 100644
--- a/src/main/java/azgracompress/utilities/Utils.java
+++ b/src/main/java/azgracompress/utilities/Utils.java
@@ -1,6 +1,7 @@
 package azgracompress.utilities;
 
 import azgracompress.U16;
+import azgracompress.data.Range;
 
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -10,6 +11,10 @@ import java.util.ArrayList;
 
 public class Utils {
 
+    public static Range<Integer> singlePlaneRange(final int index) {
+        return new Range<>(index, index + 1);
+    }
+
     public static double calculatePsnr(final double mse, final int signalMax) {
         double psnr = 10.0 * Math.log10((Math.pow(signalMax, 2) / mse));
         return psnr;
@@ -19,7 +24,7 @@ public class Utils {
         FileInputStream fileStream = new FileInputStream(path);
         try {
             throw new FileNotFoundException("Implement this actually!");
-//            return fileStream.readAllBytes();
+            //            return fileStream.readAllBytes();
         } catch (IOException e) {
             e.printStackTrace();
         }