diff --git a/src/main/java/azgracompress/benchmark/ScalarQuantizationBenchmark.java b/src/main/java/azgracompress/benchmark/ScalarQuantizationBenchmark.java
index 13f3b7aa5c405b8a0fd89d5bd72d950fe054d294..70f7ecb6b3542cf868344b3cadf48ca900661c62 100644
--- a/src/main/java/azgracompress/benchmark/ScalarQuantizationBenchmark.java
+++ b/src/main/java/azgracompress/benchmark/ScalarQuantizationBenchmark.java
@@ -4,7 +4,8 @@ import azgracompress.U16;
 import azgracompress.cli.ParsedCliOptions;
 import azgracompress.de.DeException;
 import azgracompress.de.shade.ILShadeSolver;
-import azgracompress.io.ConcretePlaneLoader;
+import azgracompress.io.IPlaneLoader;
+import azgracompress.io.PlaneLoaderFactory;
 import azgracompress.quantization.QTrainIteration;
 import azgracompress.quantization.QuantizationValueCache;
 import azgracompress.quantization.scalar.LloydMaxU16ScalarQuantization;
@@ -25,9 +26,9 @@ public class ScalarQuantizationBenchmark extends BenchmarkBase {
 
     @Override
     public void startBenchmark() {
-        ConcretePlaneLoader planeLoader = null;
+        IPlaneLoader planeLoader;
         try {
-            planeLoader = new ConcretePlaneLoader(options.getInputFileInfo());
+            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(options.getInputFileInfo());
         } catch (Exception e) {
             e.printStackTrace();
             System.err.println("Unable to create SCIFIO reader.");
diff --git a/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java b/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java
index ebae87d18614acc4b3876f727139b376c2861f77..93c63085eb5dd56c7d5abcc84c03a2485d3ef650 100644
--- a/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java
+++ b/src/main/java/azgracompress/benchmark/VectorQuantizationBenchmark.java
@@ -2,7 +2,8 @@ package azgracompress.benchmark;
 
 import azgracompress.cli.ParsedCliOptions;
 import azgracompress.data.*;
-import azgracompress.io.ConcretePlaneLoader;
+import azgracompress.io.IPlaneLoader;
+import azgracompress.io.PlaneLoaderFactory;
 import azgracompress.quantization.QuantizationValueCache;
 import azgracompress.quantization.vector.CodebookEntry;
 import azgracompress.quantization.vector.LBGResult;
@@ -48,9 +49,9 @@ public class VectorQuantizationBenchmark extends BenchmarkBase {
         if (planes.length < 1) {
             return;
         }
-        ConcretePlaneLoader planeLoader = null;
+        IPlaneLoader planeLoader;
         try {
-            planeLoader = new ConcretePlaneLoader(options.getInputFileInfo());
+            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(options.getInputFileInfo());
         } catch (Exception e) {
             e.printStackTrace();
             System.err.println("Unable to create SCIFIO reader.");
diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java
index 8dadac015b53275b0248598fc76714a2302a119e..a45a73badf77d3b31aa4e6d75666af637e285d2c 100644
--- a/src/main/java/azgracompress/compression/SQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/SQImageCompressor.java
@@ -5,7 +5,8 @@ import azgracompress.cli.InputFileInfo;
 import azgracompress.cli.ParsedCliOptions;
 import azgracompress.compression.exception.ImageCompressionException;
 import azgracompress.data.ImageU16;
-import azgracompress.io.ConcretePlaneLoader;
+import azgracompress.io.IPlaneLoader;
+import azgracompress.io.PlaneLoaderFactory;
 import azgracompress.io.OutBitStream;
 import azgracompress.quantization.QuantizationValueCache;
 import azgracompress.quantization.scalar.LloydMaxU16ScalarQuantization;
@@ -85,9 +86,9 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
         Stopwatch stopwatch = new Stopwatch();
         final boolean hasGeneralQuantizer = options.hasCodebookCacheFolder() || options.hasReferencePlaneIndex();
 
-        final ConcretePlaneLoader planeLoader;
+        final IPlaneLoader planeLoader;
         try {
-            planeLoader = new ConcretePlaneLoader(inputFileInfo);
+            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(inputFileInfo);
         } catch (Exception e) {
             throw new ImageCompressionException("Unable to create SCIFIO reader. " + e.getMessage());
         }
@@ -155,9 +156,9 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
 
     private int[] loadConfiguredPlanesData() throws ImageCompressionException {
         final InputFileInfo inputFileInfo = options.getInputFileInfo();
-        final ConcretePlaneLoader planeLoader;
+        final IPlaneLoader planeLoader;
         try {
-            planeLoader = new ConcretePlaneLoader(inputFileInfo);
+            planeLoader =  PlaneLoaderFactory.getPlaneLoaderForInputFile(inputFileInfo);
         } catch (Exception e) {
             throw new ImageCompressionException("Unable to create SCIFIO reader. " + e.getMessage());
         }
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
index b4c85a443db033aeacfa224541dd088e589b4738..2e69dd6c804cc33b199f42810a1387c4a85bd2d7 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -5,7 +5,7 @@ import azgracompress.cli.ParsedCliOptions;
 import azgracompress.compression.exception.ImageCompressionException;
 import azgracompress.data.Chunk2D;
 import azgracompress.data.ImageU16;
-import azgracompress.io.ConcretePlaneLoader;
+import azgracompress.io.PlaneLoaderFactory;
 import azgracompress.io.IPlaneLoader;
 import azgracompress.io.OutBitStream;
 import azgracompress.quantization.QuantizationValueCache;
@@ -91,9 +91,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
         final InputFileInfo inputFileInfo = options.getInputFileInfo();
         Stopwatch stopwatch = new Stopwatch();
         final boolean hasGeneralQuantizer = options.hasCodebookCacheFolder() || options.hasReferencePlaneIndex();
-        final ConcretePlaneLoader planeLoader;
+        final IPlaneLoader planeLoader;
         try {
-            planeLoader = new ConcretePlaneLoader(inputFileInfo);
+            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(inputFileInfo);
         } catch (Exception e) {
             throw new ImageCompressionException("Unable to create SCIFIO reader. " + e.getMessage());
         }
@@ -177,9 +177,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
     private int[][] loadConfiguredPlanesData() throws ImageCompressionException {
         final int vectorSize = options.getVectorDimension().getX() * options.getVectorDimension().getY();
         final InputFileInfo inputFileInfo = options.getInputFileInfo();
-        final ConcretePlaneLoader planeLoader;
+        final IPlaneLoader planeLoader;
         try {
-            planeLoader = new ConcretePlaneLoader(inputFileInfo);
+            planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(inputFileInfo);
         } catch (Exception e) {
             throw new ImageCompressionException("Unable to create SCIFIO reader. " + e.getMessage());
         }
diff --git a/src/main/java/azgracompress/io/ConcretePlaneLoader.java b/src/main/java/azgracompress/io/ConcretePlaneLoader.java
deleted file mode 100644
index 12d7346a60c1ab3e4d0cbc6fe7e486bc002836dd..0000000000000000000000000000000000000000
--- a/src/main/java/azgracompress/io/ConcretePlaneLoader.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package azgracompress.io;
-
-import azgracompress.cli.InputFileInfo;
-import azgracompress.data.ImageU16;
-
-import java.io.IOException;
-
-public class ConcretePlaneLoader implements IPlaneLoader {
-
-    private final IPlaneLoader loader;
-
-    private final InputFileInfo inputFileInfo;
-
-    /**
-     * Create plane loader.
-     *
-     * @param inputFileInfo Information about input file.
-     * @throws Exception When fails to create SCIFIO reader.
-     */
-    public ConcretePlaneLoader(final InputFileInfo inputFileInfo) throws Exception {
-        this.inputFileInfo = inputFileInfo;
-
-        if (inputFileInfo.isRAW()) {
-            loader = new RawDataLoader(inputFileInfo);
-        } else {
-            loader = new SCIFIOLoader(inputFileInfo);
-        }
-    }
-
-
-    @Override
-    public ImageU16 loadPlaneU16(int plane) throws IOException {
-        return loader.loadPlaneU16(plane);
-    }
-
-    @Override
-    public int[] loadPlanesU16Data(int[] planes) throws IOException {
-        return loader.loadPlanesU16Data(planes);
-    }
-
-    @Override
-    public int[] loadAllPlanesU16Data() throws IOException {
-        return loader.loadAllPlanesU16Data();
-    }
-}
diff --git a/src/main/java/azgracompress/io/PlaneLoaderFactory.java b/src/main/java/azgracompress/io/PlaneLoaderFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb9b77b52b5e56db8f7466ab6048ee286261b168
--- /dev/null
+++ b/src/main/java/azgracompress/io/PlaneLoaderFactory.java
@@ -0,0 +1,21 @@
+package azgracompress.io;
+
+import azgracompress.cli.InputFileInfo;
+
+public final class PlaneLoaderFactory {
+
+    /**
+     * Create concrete plane loader for the input file.
+     *
+     * @param inputFileInfo Input file information.
+     * @return Concrete plane loader.
+     * @throws Exception When fails to create plane loader.
+     */
+    public static IPlaneLoader getPlaneLoaderForInputFile(final InputFileInfo inputFileInfo) throws Exception {
+        if (inputFileInfo.isRAW()) {
+            return new RawDataLoader(inputFileInfo);
+        } else {
+            return new SCIFIOLoader(inputFileInfo);
+        }
+    }
+}