diff --git a/src/main/java/azgracompress/compression/ImageCompressor.java b/src/main/java/azgracompress/compression/ImageCompressor.java
index 9f0ed92889886b34ca612f49e23fd08a3be5ba59..9d4b817291d0e44f8af6d52953a9a53eb5185356 100644
--- a/src/main/java/azgracompress/compression/ImageCompressor.java
+++ b/src/main/java/azgracompress/compression/ImageCompressor.java
@@ -1,21 +1,11 @@
 package azgracompress.compression;
 
 import azgracompress.cli.ParsedCliOptions;
-import azgracompress.data.Chunk2D;
-import azgracompress.data.ImageU16;
-import azgracompress.data.V2i;
 import azgracompress.fileformat.QCMPFileHeader;
-import azgracompress.io.OutBitStream;
-import azgracompress.io.RawDataIO;
-import azgracompress.quantization.vector.CodebookEntry;
-import azgracompress.quantization.vector.LBGResult;
-import azgracompress.quantization.vector.LBGVectorQuantizer;
-import azgracompress.quantization.vector.VectorQuantizer;
 
 import java.io.BufferedOutputStream;
 import java.io.DataOutputStream;
 import java.io.FileOutputStream;
-import java.io.IOException;
 
 public class ImageCompressor extends CompressorDecompressorBase {
 
@@ -32,96 +22,37 @@ public class ImageCompressor extends CompressorDecompressorBase {
         Log(String.format("Compression with BPP = %d", options.getBitsPerPixel()));
 
         FileOutputStream fos = new FileOutputStream(options.getOutputFile(), false);
-        DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(fos, 8192));
+        DataOutputStream compressStream = new DataOutputStream(new BufferedOutputStream(fos, 8192));
 
         // Create and write header to output stream.
         final QCMPFileHeader header = createHeader();
-        header.writeHeader(dataOutputStream);
+        header.writeHeader(compressStream);
 
         boolean compressionResult = true;
         switch (options.getQuantizationType()) {
             case Scalar: {
                 SQImageCompressor compressor = new SQImageCompressor(options);
-                compressor.compress(dataOutputStream);
+                compressor.compress(compressStream);
             }
             break;
             case Vector1D:
-            case Vector2D:
-                compressUsingVectorQuantization(dataOutputStream);
-                break;
+            case Vector2D: {
+                VQImageCompressor compressor = new VQImageCompressor(options);
+                compressor.compress(compressStream);
+            }
+            break;
             case Vector3D:
             case Invalid:
                 throw new Exception("Not supported quantization type");
         }
 
-        dataOutputStream.flush();
+        compressStream.flush();
         fos.flush();
 
-        dataOutputStream.close();
+        compressStream.close();
         fos.close();
     }
 
-    private int[][] getPlaneVectors(final ImageU16 plane) {
-        final V2i qVector = options.getVectorDimension();
-
-        if (qVector.getY() > 1) {
-            // 2D Quantization.
-            return Chunk2D.chunksAsImageVectors(plane.as2dChunk().divideIntoChunks(qVector));
-        } else {
-            // 1D Quantization.
-            return plane.as2dChunk().divideInto1DVectors(qVector.getX());
-        }
-    }
-
-    private VectorQuantizer trainVectorQuantizerFromPlaneVectors(final int[][] planeVectors) {
-        LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(planeVectors, codebookSize);
-        LBGResult vqResult = vqInitializer.findOptimalCodebook(false);
-        // TODO(Moravec): If verbose ask initializer for result.
-        return new VectorQuantizer(vqResult.getCodebook());
-    }
-
-    private void compressUsingVectorQuantization(DataOutputStream compressStream) throws Exception {
-        VectorQuantizer quantizer = null;
-        if (options.hasReferencePlaneIndex()) {
-            final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
-                                                                   options.getImageDimension(),
-                                                                   options.getReferencePlaneIndex());
-
-            Log("Creating codebook from reference plane...");
-            final int[][] refPlaneVectors = getPlaneVectors(referencePlane);
-            quantizer = trainVectorQuantizerFromPlaneVectors(refPlaneVectors);
-            writeCodebookToOutputStream(quantizer, compressStream);
-            Log("Wrote reference codebook.");
-        }
-
-        final int[] planeIndices = getPlaneIndicesForCompression();
-
-        for (final int planeIndex : planeIndices) {
-            Log(String.format("Loading plane %d...", planeIndex));
-            final ImageU16 plane = RawDataIO.loadImageU16(options.getInputFile(),
-                                                          options.getImageDimension(),
-                                                          planeIndex);
-
-            final int[][] planeVectors = getPlaneVectors(plane);
-
-            if (!options.hasReferencePlaneIndex()) {
-                Log("Creating plane codebook...");
-                quantizer = trainVectorQuantizerFromPlaneVectors(planeVectors);
-                writeCodebookToOutputStream(quantizer, compressStream);
-                Log("Wrote plane codebook.");
-            }
-
-            assert (quantizer != null);
-
-            Log("Writing quantization indices...");
-            final int[] indices = quantizer.quantizeIntoIndices(planeVectors);
-
-            OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048);
-            outBitStream.write(indices);
-            outBitStream.flush();
-            Log(String.format("Finished processing of plane %d", planeIndex));
-        }
-    }
 
     private QCMPFileHeader createHeader() {
         QCMPFileHeader header = new QCMPFileHeader();
@@ -144,14 +75,5 @@ public class ImageCompressor extends CompressorDecompressorBase {
         return header;
     }
 
-    private void writeCodebookToOutputStream(final VectorQuantizer quantizer,
-                                             DataOutputStream compressStream) throws IOException {
-        final CodebookEntry[] codebook = quantizer.getCodebook();
-        for (final CodebookEntry entry : codebook) {
-            final int[] entryVector = entry.getVector();
-            for (final int vecVal : entryVector) {
-                compressStream.writeShort(vecVal);
-            }
-        }
-    }
+
 }
diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java
index fd5a59e61f7b8def46d732f32ff438929c09011d..8d0881e3d11f3462ed8d34ed8cc7283c3ebe5564 100644
--- a/src/main/java/azgracompress/compression/SQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/SQImageCompressor.java
@@ -46,7 +46,7 @@ public class SQImageCompressor extends CompressorDecompressorBase {
     }
 
     /**
-     * Compress the image file specified by parsed CLI options using scalar quantization..
+     * 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.
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
index cfb69b8ea0072a5f59d5b66288a9a91dda5713c8..86f4a0b3b018a14b5832ded77fffc0bbf88a69b3 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -1,4 +1,121 @@
 package azgracompress.compression;
 
-public class VQImageCompressor {
+import azgracompress.cli.ParsedCliOptions;
+import azgracompress.data.Chunk2D;
+import azgracompress.data.ImageU16;
+import azgracompress.data.V2i;
+import azgracompress.io.OutBitStream;
+import azgracompress.io.RawDataIO;
+import azgracompress.quantization.vector.CodebookEntry;
+import azgracompress.quantization.vector.LBGResult;
+import azgracompress.quantization.vector.LBGVectorQuantizer;
+import azgracompress.quantization.vector.VectorQuantizer;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class VQImageCompressor extends CompressorDecompressorBase {
+
+    public VQImageCompressor(ParsedCliOptions options) {
+        super(options);
+    }
+
+    /**
+     * Get image vectors from the plane. Vector dimensions are specified by parsed CLI options.
+     *
+     * @param plane Image plane.
+     * @return Image vectors.
+     */
+    private int[][] getPlaneVectors(final ImageU16 plane) {
+        final V2i qVector = options.getVectorDimension();
+
+        if (qVector.getY() > 1) {
+            // 2D Quantization, return `matrices`.
+            return Chunk2D.chunksAsImageVectors(plane.as2dChunk().divideIntoChunks(qVector));
+        } else {
+            // 1D Quantization, return row vectors.
+            return plane.as2dChunk().divideInto1DVectors(qVector.getX());
+        }
+    }
+
+    /**
+     * Train vector quantizer from plane vectors.
+     *
+     * @param planeVectors Image vectors.
+     * @return Trained vector quantizer with codebook of set size.
+     */
+    private VectorQuantizer trainVectorQuantizerFromPlaneVectors(final int[][] planeVectors) {
+        LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(planeVectors, codebookSize);
+        LBGResult vqResult = vqInitializer.findOptimalCodebook(false);
+        return new VectorQuantizer(vqResult.getCodebook());
+    }
+
+    /**
+     * Write the vector codebook to the compress stream.
+     *
+     * @param quantizer      Quantizer with the codebook.
+     * @param compressStream Stream with compressed data.
+     * @throws IOException When unable to write quantizer.
+     */
+    private void writeQuantizerToCompressStream(final VectorQuantizer quantizer,
+                                                DataOutputStream compressStream) throws IOException {
+        final CodebookEntry[] codebook = quantizer.getCodebook();
+        for (final CodebookEntry entry : codebook) {
+            final int[] entryVector = entry.getVector();
+            for (final int vecVal : entryVector) {
+                compressStream.writeShort(vecVal);
+            }
+        }
+    }
+
+    /**
+     * 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.
+     */
+    public void compress(DataOutputStream compressStream) throws Exception {
+        VectorQuantizer quantizer = null;
+        if (options.hasReferencePlaneIndex()) {
+            final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
+                                                                   options.getImageDimension(),
+                                                                   options.getReferencePlaneIndex());
+
+            Log("Creating codebook from reference plane...");
+            final int[][] refPlaneVectors = getPlaneVectors(referencePlane);
+            quantizer = trainVectorQuantizerFromPlaneVectors(refPlaneVectors);
+            writeQuantizerToCompressStream(quantizer, compressStream);
+            Log("Wrote reference codebook.");
+        }
+
+        final int[] planeIndices = getPlaneIndicesForCompression();
+
+        for (final int planeIndex : planeIndices) {
+            Log(String.format("Loading plane %d...", planeIndex));
+            final ImageU16 plane = RawDataIO.loadImageU16(options.getInputFile(),
+                                                          options.getImageDimension(),
+                                                          planeIndex);
+
+            final int[][] planeVectors = getPlaneVectors(plane);
+
+            if (!options.hasReferencePlaneIndex()) {
+                Log("Creating plane codebook...");
+                quantizer = trainVectorQuantizerFromPlaneVectors(planeVectors);
+                writeQuantizerToCompressStream(quantizer, compressStream);
+                Log("Wrote plane codebook.");
+            }
+
+            assert (quantizer != null);
+
+            Log("Writing quantization indices...");
+            final int[] indices = quantizer.quantizeIntoIndices(planeVectors);
+
+            OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048);
+            outBitStream.write(indices);
+            outBitStream.flush();
+            Log(String.format("Finished processing of plane %d", planeIndex));
+        }
+    }
+
+
 }