diff --git a/src/main/java/azgracompress/benchmark/BenchmarkBase.java b/src/main/java/azgracompress/benchmark/BenchmarkBase.java
index d70ab9f6ab961ff0d0273c88a9f30d13e97072b0..7a6b629990a55c19176dca4f2915294f193ad701 100644
--- a/src/main/java/azgracompress/benchmark/BenchmarkBase.java
+++ b/src/main/java/azgracompress/benchmark/BenchmarkBase.java
@@ -1,6 +1,6 @@
 package azgracompress.benchmark;
 
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.InputData;
 import azgracompress.cli.ParsedCliOptions;
 import azgracompress.data.ImageU16;
 import azgracompress.data.V3i;
@@ -40,7 +40,7 @@ abstract class BenchmarkBase {
     protected BenchmarkBase(final ParsedCliOptions options) {
         this.options = options;
 
-        final InputDataInfo ifi = options.getInputDataInfo();
+        final InputData ifi = options.getInputDataInfo();
         this.inputFile = ifi.getFilePath();
         this.outputDirectory = options.getOutputFilePath();
 
diff --git a/src/main/java/azgracompress/cli/ParsedCliOptions.java b/src/main/java/azgracompress/cli/ParsedCliOptions.java
index a45d7eb5c53c562d6c52ce757bb64ac623e55d0a..524efef8db5091494dc287546b051994ed0a7fb8 100644
--- a/src/main/java/azgracompress/cli/ParsedCliOptions.java
+++ b/src/main/java/azgracompress/cli/ParsedCliOptions.java
@@ -8,7 +8,8 @@ import azgracompress.data.V2i;
 import azgracompress.data.V3i;
 import azgracompress.fileformat.FileExtensions;
 import azgracompress.fileformat.QuantizationType;
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.FileInputData;
+import azgracompress.io.InputData;
 import io.scif.FormatException;
 import io.scif.Plane;
 import io.scif.Reader;
@@ -139,7 +140,7 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
         setCodebookCacheFolder(cmd.getOptionValue(CliConstants.CODEBOOK_CACHE_FOLDER_LONG, null));
 
         if (!parseErrorOccurred) {
-            setOutputFilePath(cmd.getOptionValue(CliConstants.OUTPUT_LONG, getDefaultOutputFilePath(getInputDataInfo().getFilePath())));
+            setOutputFilePath(cmd.getOptionValue(CliConstants.OUTPUT_LONG, getDefaultOutputFilePath(((FileInputData) getInputDataInfo()).getFilePath())));
             setCodebookCacheFolder(cmd.getOptionValue(CliConstants.CODEBOOK_CACHE_FOLDER_LONG, null));
         }
 
@@ -162,7 +163,8 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
             return;
         }
 
-        setInputDataInfo(new InputDataInfo(inputFileArguments[0]));
+        final FileInputData fileInputData = new FileInputData(inputFileArguments[0]);
+        setInputDataInfo(fileInputData);
 
         // Decompress and Inspect methods doesn't require additional file information.
         if ((method == ProgramMethod.Decompress) || (method == ProgramMethod.InspectFile)) {
@@ -170,7 +172,7 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
         }
 
         // Check if input file exists.
-        if (!new File(getInputDataInfo().getFilePath()).exists()) {
+        if (!new File(fileInputData.getFilePath()).exists()) {
             parseErrorOccurred = true;
             errorBuilder.append("Input file doesn't exist.\n");
             return;
@@ -187,10 +189,10 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
 
 
     private void parseSCIFIOFileArguments(StringBuilder errorBuilder, final String[] inputFileArguments) {
-        getInputDataInfo().setDataLoaderType(InputDataInfo.DataLoaderType.SCIFIOLoader);
+        getInputDataInfo().setDataLoaderType(InputData.DataLoaderType.SCIFIOLoader);
         Reader reader;
         try {
-            reader = ScifioWrapper.getReader(getInputDataInfo().getFilePath());
+            reader = ScifioWrapper.getReader(((FileInputData)getInputDataInfo()).getFilePath());
         } catch (IOException | FormatException e) {
             parseErrorOccurred = true;
             errorBuilder.append("Failed to get SCIFIO reader for file.\n");
@@ -251,7 +253,7 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
                     .append("e.g.: 1920x1080x1\n");
             return;
         }
-        getInputDataInfo().setDataLoaderType(InputDataInfo.DataLoaderType.RawDataLoader);
+        getInputDataInfo().setDataLoaderType(InputData.DataLoaderType.RawDataLoader);
         parseImageDims(inputFileArguments[1], errorBuilder);
 
         // User specified plane index or plane range.
@@ -542,7 +544,7 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
         }
 
 
-        sb.append("InputFile: ").append(getInputDataInfo().getFilePath()).append('\n');
+        sb.append("InputFile: ").append(((FileInputData)getInputDataInfo()).getFilePath()).append('\n');
         sb.append("Output: ").append(getOutputFilePath()).append('\n');
         sb.append("BitsPerCodebookIndex: ").append(getBitsPerCodebookIndex()).append('\n');
         if (hasCodebookCacheFolder()) {
diff --git a/src/main/java/azgracompress/cli/functions/MeasurePlaneErrorFunction.java b/src/main/java/azgracompress/cli/functions/MeasurePlaneErrorFunction.java
index 5ab882dc94b02762764e2435ccd0da0c3ddd856e..6b6e4e1b48a73ffa509bb5d219c19d71a9b17d02 100644
--- a/src/main/java/azgracompress/cli/functions/MeasurePlaneErrorFunction.java
+++ b/src/main/java/azgracompress/cli/functions/MeasurePlaneErrorFunction.java
@@ -1,7 +1,8 @@
 package azgracompress.cli.functions;
 
 import azgracompress.cli.CustomFunctionBase;
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.FileInputData;
+import azgracompress.io.InputData;
 import azgracompress.cli.ParsedCliOptions;
 import azgracompress.data.ImageU16;
 import azgracompress.data.V3i;
@@ -125,9 +126,9 @@ public class MeasurePlaneErrorFunction extends CustomFunctionBase {
 
         PlaneError[] planeErrors = new PlaneError[dims.getZ()];
 
-        InputDataInfo refFileInfo = new InputDataInfo(compFile);
+        InputData refFileInfo = new FileInputData(compFile);
         refFileInfo.setDimension(dims);
-        InputDataInfo compFileInfo = new InputDataInfo(compressedFile);
+        InputData compFileInfo = new FileInputData(compressedFile);
         compFileInfo.setDimension(dims);
 
         final RawDataLoader refPlaneloader = new RawDataLoader(refFileInfo);
diff --git a/src/main/java/azgracompress/compression/CompressionOptions.java b/src/main/java/azgracompress/compression/CompressionOptions.java
index 5c41a6113236a80e61a448c7da8befe0dd7a2c30..53738f953bbd70974793abf64d0338864467e78f 100644
--- a/src/main/java/azgracompress/compression/CompressionOptions.java
+++ b/src/main/java/azgracompress/compression/CompressionOptions.java
@@ -1,8 +1,7 @@
 package azgracompress.compression;
 
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.InputData;
 import azgracompress.data.V2i;
-import azgracompress.data.V3i;
 import azgracompress.fileformat.QuantizationType;
 
 /**
@@ -12,7 +11,7 @@ public class CompressionOptions {
     /**
      * Input image or compressed file.
      */
-    private InputDataInfo inputDataInfo;
+    private InputData inputDataInfo;
 
     /**
      * Output image or compressed file.
@@ -70,11 +69,11 @@ public class CompressionOptions {
         return verbose;
     }
 
-    public InputDataInfo getInputDataInfo() {
+    public InputData getInputDataInfo() {
         return inputDataInfo;
     }
 
-    public void setInputDataInfo(InputDataInfo ifi) {
+    public void setInputDataInfo(InputData ifi) {
         this.inputDataInfo = ifi;
     }
 
diff --git a/src/main/java/azgracompress/compression/CompressorDecompressorBase.java b/src/main/java/azgracompress/compression/CompressorDecompressorBase.java
index fd9d9e28eeb9d3418acceb268d691e1e4a626202..ececf9d4997f16227fe079de763a94799dd8f0a1 100644
--- a/src/main/java/azgracompress/compression/CompressorDecompressorBase.java
+++ b/src/main/java/azgracompress/compression/CompressorDecompressorBase.java
@@ -1,6 +1,6 @@
 package azgracompress.compression;
 
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.InputData;
 import azgracompress.compression.exception.ImageCompressionException;
 import azgracompress.huffman.Huffman;
 import azgracompress.io.OutBitStream;
@@ -50,7 +50,7 @@ public abstract class CompressorDecompressorBase {
 
     protected int[] getPlaneIndicesForCompression() {
 
-        final InputDataInfo ifi = options.getInputDataInfo();
+        final InputData ifi = options.getInputDataInfo();
         if (ifi.isPlaneIndexSet()) {
             return new int[]{ifi.getPlaneIndex()};
         } else if (ifi.isPlaneRangeSet()) {
diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java
index a1cda6314231c0bd00d4aa6df3b6e875ad536286..c0cab1ec261360dd76c5e6fb500372d5ba9d08d6 100644
--- a/src/main/java/azgracompress/compression/SQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/SQImageCompressor.java
@@ -2,7 +2,7 @@ package azgracompress.compression;
 
 import azgracompress.U16;
 import azgracompress.cache.QuantizationCacheManager;
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.InputData;
 import azgracompress.compression.exception.ImageCompressionException;
 import azgracompress.data.ImageU16;
 import azgracompress.huffman.Huffman;
@@ -88,7 +88,7 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
      * @throws ImageCompressionException When compress process fails.
      */
     public long[] compress(DataOutputStream compressStream) throws ImageCompressionException {
-        final InputDataInfo inputDataInfo = options.getInputDataInfo();
+        final InputData inputDataInfo = options.getInputDataInfo();
         Stopwatch stopwatch = new Stopwatch();
         final boolean hasGeneralQuantizer = options.hasCodebookCacheFolder() || options.shouldUseMiddlePlane();
 
@@ -171,7 +171,7 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
     }
 
     private int[] loadConfiguredPlanesData() throws ImageCompressionException {
-        final InputDataInfo inputDataInfo = options.getInputDataInfo();
+        final InputData inputDataInfo = options.getInputDataInfo();
         final IPlaneLoader planeLoader;
         try {
             planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(inputDataInfo);
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
index a64d23528bd1ac0087ff3ac5b1d2f3de71c513e1..3979841e7d136da0f6c5b4a58421198477889e3e 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -1,7 +1,7 @@
 package azgracompress.compression;
 
 import azgracompress.cache.QuantizationCacheManager;
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.InputData;
 import azgracompress.compression.exception.ImageCompressionException;
 import azgracompress.data.Chunk2D;
 import azgracompress.data.ImageU16;
@@ -92,7 +92,7 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
      * @throws ImageCompressionException When compress process fails.
      */
     public long[] compress(DataOutputStream compressStream) throws ImageCompressionException {
-        final InputDataInfo inputDataInfo = options.getInputDataInfo();
+        final InputData inputDataInfo = options.getInputDataInfo();
         Stopwatch stopwatch = new Stopwatch();
         final boolean hasGeneralQuantizer = options.hasCodebookCacheFolder() || options.shouldUseMiddlePlane();
         final IPlaneLoader planeLoader;
@@ -189,7 +189,7 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
 
     private int[][] loadConfiguredPlanesData() throws ImageCompressionException {
         final int vectorSize = options.getVectorDimension().getX() * options.getVectorDimension().getY();
-        final InputDataInfo inputDataInfo = options.getInputDataInfo();
+        final InputData inputDataInfo = options.getInputDataInfo();
         final IPlaneLoader planeLoader;
         try {
             planeLoader = PlaneLoaderFactory.getPlaneLoaderForInputFile(inputDataInfo);
diff --git a/src/main/java/azgracompress/io/BufferInputData.java b/src/main/java/azgracompress/io/BufferInputData.java
new file mode 100644
index 0000000000000000000000000000000000000000..1afbed7e2421800a8c47c9d7383b126202c7f9ba
--- /dev/null
+++ b/src/main/java/azgracompress/io/BufferInputData.java
@@ -0,0 +1,29 @@
+package azgracompress.io;
+
+/**
+ * Input data backed by the buffer object.
+ */
+public class BufferInputData extends InputData {
+
+    /**
+     * Reference to the buffer.
+     */
+    private final Object buffer;
+
+
+    /**
+     * Create input data backed by buffer object.
+     * @param buffer Buffer object reference.
+     */
+    public BufferInputData(Object buffer) {
+        this.buffer = buffer;
+    }
+
+    /**
+     * Get buffer with the data.
+     * @return Pointer to array of corresponding pixel values.
+     */
+    public Object getBuffer() {
+        return buffer;
+    }
+}
diff --git a/src/main/java/azgracompress/io/FileInputData.java b/src/main/java/azgracompress/io/FileInputData.java
new file mode 100644
index 0000000000000000000000000000000000000000..49fad663a4d9653f3647cbc24949ba660416f219
--- /dev/null
+++ b/src/main/java/azgracompress/io/FileInputData.java
@@ -0,0 +1,29 @@
+package azgracompress.io;
+
+/**
+ * Input data backed by the file.
+ */
+public class FileInputData extends InputData {
+
+    /**
+     * Input file path.
+     */
+    private final String filePath;
+
+    /**
+     * Create input data backed by data file.
+     * @param filePath
+     */
+    public FileInputData(String filePath) {
+        this.filePath = filePath;
+    }
+
+    /**
+     * Get path to the data file.
+     * @return
+     */
+    @Override
+    public String getFilePath() {
+        return filePath;
+    }
+}
diff --git a/src/main/java/azgracompress/io/InputDataInfo.java b/src/main/java/azgracompress/io/InputData.java
similarity index 75%
rename from src/main/java/azgracompress/io/InputDataInfo.java
rename to src/main/java/azgracompress/io/InputData.java
index 3255a6428d54f69dc5983c577c9c0c4c52d58eae..781503a9d575d2cae29b78e1bb1bfe006d841cc3 100644
--- a/src/main/java/azgracompress/io/InputDataInfo.java
+++ b/src/main/java/azgracompress/io/InputData.java
@@ -6,23 +6,29 @@ import azgracompress.data.V3i;
 /**
  * Information about the input file.
  */
-public class InputDataInfo {
+public abstract class InputData {
     public enum DataLoaderType {
         RawDataLoader,
         SCIFIOLoader,
         ImageJBufferLoader
     }
 
-    /**
-     * Input file path.
-     */
-    private final String filePath;
+    public enum PixelType {
+        Gray16,
+        AnythingElse
+    }
+
 
     /**
      * Type of an input data source.
      */
     private DataLoaderType dataLoaderType = DataLoaderType.RawDataLoader;
 
+    /**
+     * Pixel type of the image data.
+     */
+    private PixelType pixelType = PixelType.Gray16;
+
     /**
      * Image dimension.
      */
@@ -38,9 +44,6 @@ public class InputDataInfo {
      */
     Interval<Integer> planeRange = null;
 
-    public InputDataInfo(final String filePath) {
-        this.filePath = filePath;
-    }
 
     public boolean isPlaneIndexSet() {
         return (planeIndex != null);
@@ -54,9 +57,6 @@ public class InputDataInfo {
         this.dimension = dimension;
     }
 
-    public String getFilePath() {
-        return filePath;
-    }
 
     public V3i getDimensions() {
         return dimension;
@@ -85,4 +85,24 @@ public class InputDataInfo {
     public void setDataLoaderType(DataLoaderType dataLoaderType) {
         this.dataLoaderType = dataLoaderType;
     }
+
+    public PixelType getPixelType() {
+        return pixelType;
+    }
+
+    public void setPixelType(PixelType pixelType) {
+        this.pixelType = pixelType;
+    }
+
+    public V3i getDimension() {
+        return dimension;
+    }
+
+    /**
+     * Override in FileInputData!!!
+     * @return null!
+     */
+    public String getFilePath() {
+        return null;
+    }
 }
diff --git a/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java b/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
index 80a0bc241ac57901570b325f0cae52953b7de0c6..4fbb69fb66625362c7b1b686fb62331e56c66bf3 100644
--- a/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
+++ b/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
@@ -1,6 +1,6 @@
 package azgracompress.io.loader;
 
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.InputData;
 
 public final class PlaneLoaderFactory {
 
@@ -11,17 +11,17 @@ public final class PlaneLoaderFactory {
      * @return Concrete plane loader.
      * @throws Exception When fails to create plane loader.
      */
-    public static IPlaneLoader getPlaneLoaderForInputFile(final InputDataInfo inputDataInfo) throws Exception {
+    public static IPlaneLoader getPlaneLoaderForInputFile(final InputData inputDataInfo) throws Exception {
         switch (inputDataInfo.getDataLoaderType()) {
             case RawDataLoader:
                 return new RawDataLoader(inputDataInfo);
             case SCIFIOLoader:
                 return new SCIFIOLoader(inputDataInfo);
             case ImageJBufferLoader:
-                break;
+                return new ImageJBufferLoader();
             default:
                 throw new Exception("Unsupported data loader.");
         }
-        return null;
+//        return null;
     }
 }
diff --git a/src/main/java/azgracompress/io/loader/RawDataLoader.java b/src/main/java/azgracompress/io/loader/RawDataLoader.java
index 0ba46e496e06878114bc832706e56253f7c54836..b592b5b9b112806e21d1b1a69a4028ec8f3229ed 100644
--- a/src/main/java/azgracompress/io/loader/RawDataLoader.java
+++ b/src/main/java/azgracompress/io/loader/RawDataLoader.java
@@ -2,16 +2,17 @@ package azgracompress.io.loader;
 
 import azgracompress.data.ImageU16;
 import azgracompress.data.V3i;
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.FileInputData;
+import azgracompress.io.InputData;
 import azgracompress.utilities.TypeConverter;
 
 import java.io.*;
 import java.util.Arrays;
 
 public class RawDataLoader implements IPlaneLoader {
-    private final InputDataInfo inputDataInfo;
+    private final InputData inputDataInfo;
 
-    public RawDataLoader(final InputDataInfo inputDataInfo) {
+    public RawDataLoader(final InputData inputDataInfo) {
         this.inputDataInfo = inputDataInfo;
     }
 
@@ -20,7 +21,7 @@ public class RawDataLoader implements IPlaneLoader {
         byte[] buffer;
         final V3i rawDataDimension = inputDataInfo.getDimensions();
 
-        try (FileInputStream fileStream = new FileInputStream(inputDataInfo.getFilePath())) {
+        try (FileInputStream fileStream = new FileInputStream(((FileInputData)inputDataInfo).getFilePath())) {
             final long planeSize = (long) rawDataDimension.getX() * (long) rawDataDimension.getY() * 2;
             final long expectedFileSize = planeSize * rawDataDimension.getZ();
             final long fileSize = fileStream.getChannel().size();
@@ -69,7 +70,7 @@ public class RawDataLoader implements IPlaneLoader {
 
         Arrays.sort(planes);
 
-        try (FileInputStream fileStream = new FileInputStream(inputDataInfo.getFilePath());
+        try (FileInputStream fileStream = new FileInputStream(((FileInputData)inputDataInfo).getFilePath());
              DataInputStream dis = new DataInputStream(new BufferedInputStream(fileStream, 8192))) {
 
             int lastIndex = 0;
@@ -106,7 +107,7 @@ public class RawDataLoader implements IPlaneLoader {
 
         int[] values = new int[(int) dataSize];
 
-        try (FileInputStream fileStream = new FileInputStream(inputDataInfo.getFilePath());
+        try (FileInputStream fileStream = new FileInputStream(((FileInputData)inputDataInfo).getFilePath());
              DataInputStream dis = new DataInputStream(new BufferedInputStream(fileStream, 8192))) {
 
             for (int i = 0; i < (int) dataSize; i++) {
diff --git a/src/main/java/azgracompress/io/loader/SCIFIOLoader.java b/src/main/java/azgracompress/io/loader/SCIFIOLoader.java
index bfa9b6cdc315df84a8b11430e68cc53ee7e051e9..bfa7d4b92ee243addba2175506b58117f9a3bb10 100644
--- a/src/main/java/azgracompress/io/loader/SCIFIOLoader.java
+++ b/src/main/java/azgracompress/io/loader/SCIFIOLoader.java
@@ -3,7 +3,8 @@ package azgracompress.io.loader;
 import azgracompress.ScifioWrapper;
 import azgracompress.data.ImageU16;
 import azgracompress.data.V3i;
-import azgracompress.io.InputDataInfo;
+import azgracompress.io.FileInputData;
+import azgracompress.io.InputData;
 import azgracompress.utilities.TypeConverter;
 import io.scif.FormatException;
 import io.scif.Reader;
@@ -13,7 +14,7 @@ import java.util.Arrays;
 
 public class SCIFIOLoader implements IPlaneLoader {
 
-    private final InputDataInfo inputDataInfo;
+    private final InputData inputDataInfo;
     private final Reader reader;
 
     /**
@@ -23,9 +24,9 @@ public class SCIFIOLoader implements IPlaneLoader {
      * @throws IOException     When fails to create SCIFIO reader.
      * @throws FormatException When fails to create SCIFIO reader.
      */
-    public SCIFIOLoader(final InputDataInfo inputDataInfo) throws IOException, FormatException {
+    public SCIFIOLoader(final InputData inputDataInfo) throws IOException, FormatException {
         this.inputDataInfo = inputDataInfo;
-        this.reader = ScifioWrapper.getReader(this.inputDataInfo.getFilePath());
+        this.reader = ScifioWrapper.getReader(((FileInputData)this.inputDataInfo).getFilePath());
     }
 
     @Override