diff --git a/src/main/java/azgracompress/compression/CompressorDecompressorBase.java b/src/main/java/azgracompress/compression/CompressorDecompressorBase.java
index e91e4ff0a2dde7065d2887dd161a5c464d0b4f27..9b16a04b3c9689a1bc28f7aabadca395fba08372 100644
--- a/src/main/java/azgracompress/compression/CompressorDecompressorBase.java
+++ b/src/main/java/azgracompress/compression/CompressorDecompressorBase.java
@@ -6,9 +6,11 @@ public abstract class CompressorDecompressorBase {
     public static final String EXTENSTION = ".QCMP";
 
     protected final ParsedCliOptions options;
+    protected final int codebookSize;
 
     public CompressorDecompressorBase(ParsedCliOptions options) {
         this.options = options;
+        this.codebookSize = (int) Math.pow(2, this.options.getBitsPerPixel());
     }
 
     protected int[] getPlaneIndicesForCompression() {
diff --git a/src/main/java/azgracompress/compression/ImageCompressor.java b/src/main/java/azgracompress/compression/ImageCompressor.java
index cea032642f4eb9a275615c679d12184ad56a99cf..9f0ed92889886b34ca612f49e23fd08a3be5ba59 100644
--- a/src/main/java/azgracompress/compression/ImageCompressor.java
+++ b/src/main/java/azgracompress/compression/ImageCompressor.java
@@ -1,15 +1,12 @@
 package azgracompress.compression;
 
 import azgracompress.cli.ParsedCliOptions;
-import azgracompress.U16;
 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.scalar.LloydMaxU16ScalarQuantization;
-import azgracompress.quantization.scalar.ScalarQuantizer;
 import azgracompress.quantization.vector.CodebookEntry;
 import azgracompress.quantization.vector.LBGResult;
 import azgracompress.quantization.vector.LBGVectorQuantizer;
@@ -43,9 +40,11 @@ public class ImageCompressor extends CompressorDecompressorBase {
 
         boolean compressionResult = true;
         switch (options.getQuantizationType()) {
-            case Scalar:
-                compressUsingScalarQuantization(dataOutputStream);
-                break;
+            case Scalar: {
+                SQImageCompressor compressor = new SQImageCompressor(options);
+                compressor.compress(dataOutputStream);
+            }
+            break;
             case Vector1D:
             case Vector2D:
                 compressUsingVectorQuantization(dataOutputStream);
@@ -62,14 +61,6 @@ public class ImageCompressor extends CompressorDecompressorBase {
         fos.close();
     }
 
-
-    private ScalarQuantizer getScalarQuantizerFromPlane(final ImageU16 plane) {
-
-        LloydMaxU16ScalarQuantization lloydMax = new LloydMaxU16ScalarQuantization(plane.getData(), codebookSize);
-        lloydMax.train(false);
-        return new ScalarQuantizer(U16.Min, U16.Max, lloydMax.getCentroids());
-    }
-
     private int[][] getPlaneVectors(final ImageU16 plane) {
         final V2i qVector = options.getVectorDimension();
 
@@ -153,14 +144,6 @@ public class ImageCompressor extends CompressorDecompressorBase {
         return header;
     }
 
-    private void writeCodebookToOutputStream(final ScalarQuantizer quantizer,
-                                             DataOutputStream compressStream) throws IOException {
-        final int[] centroids = quantizer.getCentroids();
-        for (final int quantizationValue : centroids) {
-            compressStream.writeShort(quantizationValue);
-        }
-    }
-
     private void writeCodebookToOutputStream(final VectorQuantizer quantizer,
                                              DataOutputStream compressStream) throws IOException {
         final CodebookEntry[] codebook = quantizer.getCodebook();
@@ -171,44 +154,4 @@ public class ImageCompressor extends CompressorDecompressorBase {
             }
         }
     }
-
-
-    private void compressUsingScalarQuantization(DataOutputStream compressStream) throws Exception {
-        ScalarQuantizer quantizer = null;
-        if (options.hasReferencePlaneIndex()) {
-            final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
-                                                                   options.getImageDimension(),
-                                                                   options.getReferencePlaneIndex());
-
-            Log("Creating codebook from reference plane...");
-            quantizer = getScalarQuantizerFromPlane(referencePlane);
-            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);
-
-            if (!options.hasReferencePlaneIndex()) {
-                Log("Creating plane codebook...");
-                quantizer = getScalarQuantizerFromPlane(plane);
-                writeCodebookToOutputStream(quantizer, compressStream);
-                Log("Wrote plane codebook.");
-            }
-
-            assert (quantizer != null);
-
-            Log("Writing quantization indices...");
-            final int[] indices = quantizer.quantizeIntoIndices(plane.getData());
-            OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048);
-            outBitStream.write(indices);
-            outBitStream.flush();
-            Log(String.format("Finished processing of plane %d", planeIndex));
-        }
-    }
 }
diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd5a59e61f7b8def46d732f32ff438929c09011d
--- /dev/null
+++ b/src/main/java/azgracompress/compression/SQImageCompressor.java
@@ -0,0 +1,92 @@
+package azgracompress.compression;
+
+import azgracompress.U16;
+import azgracompress.cli.ParsedCliOptions;
+import azgracompress.data.ImageU16;
+import azgracompress.io.OutBitStream;
+import azgracompress.io.RawDataIO;
+import azgracompress.quantization.scalar.LloydMaxU16ScalarQuantization;
+import azgracompress.quantization.scalar.ScalarQuantizer;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class SQImageCompressor extends CompressorDecompressorBase {
+
+    public SQImageCompressor(ParsedCliOptions options) {
+        super(options);
+
+    }
+
+    /**
+     * Train Lloyd-Max scalar quantizer from plane data.
+     *
+     * @param planeData Plane data from which quantizer will be trained.
+     * @return Trained scalar quantizer.
+     */
+    private ScalarQuantizer trainScalarQuantizerFromData(final short[] planeData) {
+        LloydMaxU16ScalarQuantization lloydMax = new LloydMaxU16ScalarQuantization(planeData, codebookSize);
+        lloydMax.train(false);
+        return new ScalarQuantizer(U16.Min, U16.Max, lloydMax.getCentroids());
+    }
+
+    /**
+     * Writes the scalar quantizer to the compressed stream.
+     *
+     * @param quantizer      Quantizer used for compression of the image.
+     * @param compressStream Compressed data stream.
+     * @throws IOException when writing to the stream fails.
+     */
+    private void writeCodebookToOutputStream(final ScalarQuantizer quantizer,
+                                             DataOutputStream compressStream) throws IOException {
+        final int[] centroids = quantizer.getCentroids();
+        for (final int quantizationValue : centroids) {
+            compressStream.writeShort(quantizationValue);
+        }
+    }
+
+    /**
+     * 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.
+     */
+    public void compress(DataOutputStream compressStream) throws Exception {
+        ScalarQuantizer quantizer = null;
+        if (options.hasReferencePlaneIndex()) {
+            final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
+                                                                   options.getImageDimension(),
+                                                                   options.getReferencePlaneIndex());
+
+            Log("Creating codebook from reference plane...");
+            quantizer = trainScalarQuantizerFromData(referencePlane.getData());
+            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);
+
+            if (!options.hasReferencePlaneIndex()) {
+                Log("Creating plane codebook...");
+                quantizer = trainScalarQuantizerFromData(plane.getData());
+                writeCodebookToOutputStream(quantizer, compressStream);
+                Log("Wrote plane codebook.");
+            }
+
+            assert (quantizer != null);
+
+            Log("Writing quantization indices...");
+            final int[] indices = quantizer.quantizeIntoIndices(plane.getData());
+            OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048);
+            outBitStream.write(indices);
+            outBitStream.flush();
+            Log(String.format("Finished processing of plane %d", planeIndex));
+        }
+    }
+}
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfb69b8ea0072a5f59d5b66288a9a91dda5713c8
--- /dev/null
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -0,0 +1,4 @@
+package azgracompress.compression;
+
+public class VQImageCompressor {
+}