diff --git a/src/main/java/azgracompress/io/FlatBufferInputData.java b/src/main/java/azgracompress/io/FlatBufferInputData.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6eef34799b2fd5469cbefe08292e435abcbd85d
--- /dev/null
+++ b/src/main/java/azgracompress/io/FlatBufferInputData.java
@@ -0,0 +1,52 @@
+package azgracompress.io;
+
+import azgracompress.data.V3i;
+
+/**
+ * Input data backed by the single buffer object.
+ * In this buffer all the dataset pixels are stored.
+ */
+public class FlatBufferInputData extends InputData {
+    /**
+     * Reference to the buffer.
+     */
+    private final Object imageBuffer;
+
+    /**
+     * Name of the image used in caching.
+     */
+    private final String cacheHint;
+
+    /**
+     * Create input data backed by buffer object.
+     *
+     * @param imageBuffer     Image buffer reference.
+     * @param imageDimensions Image dimensions.
+     * @param pixelType       Image pixel type.
+     * @param cacheHint       Name of the image used in caching.
+     */
+    public FlatBufferInputData(final Object imageBuffer,
+                               final V3i imageDimensions,
+                               final PixelType pixelType,
+                               final String cacheHint) {
+        this.imageBuffer = imageBuffer;
+        setDataLoaderType(DataLoaderType.ImageJBufferLoader);
+        setDimension(imageDimensions);
+        setPixelType(pixelType);
+        this.cacheHint = cacheHint;
+    }
+
+    /**
+     * Get buffer with the image plane data.
+     *
+     * @return Pointer to pixel buffer.
+     */
+    public Object getPixelBuffer() {
+        return imageBuffer;
+    }
+
+    @Override
+    public String getCacheFileName() {
+        return cacheHint;
+    }
+}
diff --git a/src/main/java/azgracompress/io/loader/FlatBufferLoader.java b/src/main/java/azgracompress/io/loader/FlatBufferLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..81e5d6c013bf7fc08bbed8cdee4589360f93718f
--- /dev/null
+++ b/src/main/java/azgracompress/io/loader/FlatBufferLoader.java
@@ -0,0 +1,110 @@
+package azgracompress.io.loader;
+
+import azgracompress.data.Range;
+import azgracompress.data.V2i;
+import azgracompress.data.V3i;
+import azgracompress.io.FlatBufferInputData;
+import azgracompress.utilities.TypeConverter;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * This loader is used when the entire dataset is stored in single buffer (array).
+ */
+public class FlatBufferLoader extends BasicLoader implements IPlaneLoader {
+    /**
+     * Flat buffer information.
+     */
+    private final FlatBufferInputData bufferInputData;
+
+    /**
+     * Pixel count in single plane.
+     */
+    private final int planePixelCount;
+
+    public FlatBufferLoader(final FlatBufferInputData bufferDataInfo) {
+        super(bufferDataInfo.getDimensions());
+        this.bufferInputData = bufferDataInfo;
+        planePixelCount = dims.getX() * dims.getY();
+    }
+
+    @Override
+    public boolean supportParallelLoading() {
+        return true;
+    }
+
+    private void copyShortArrayIntoBuffer(short[] srcArray,
+                                          final int srcOffset,
+                                          int[] destBuffer,
+                                          final int destOffset,
+                                          final int copyLen) {
+        for (int i = 0; i < copyLen; i++) {
+            destBuffer[destOffset + i] = TypeConverter.shortToInt(srcArray[srcOffset + i]);
+        }
+    }
+
+    @Override
+    protected int valueAt(final int plane, final int offset) {
+        return TypeConverter.shortToInt(((short[]) bufferInputData.getPixelBuffer())[(plane * planePixelCount) + offset]);
+    }
+
+    @Override
+    public int[] loadPlaneData(final int plane) throws IOException {
+        final short[] flatBuffer = ((short[]) bufferInputData.getPixelBuffer());
+        final int offset = plane * planePixelCount;
+        final int[] planeData = new int[planePixelCount];
+        for (int i = 0; i < planePixelCount; i++) {
+            planeData[i] = TypeConverter.shortToInt(flatBuffer[offset + i]);
+        }
+        return planeData;
+    }
+
+    @Override
+    public int[] loadPlanesU16Data(final int[] planes) throws IOException {
+        if (planes.length < 1) {
+            return new int[0];
+        } else if (planes.length == 1) {
+            return loadPlaneData(planes[0]);
+        } else if (planes.length == bufferInputData.getDimensions().getZ()) { // Maybe?
+            return loadAllPlanesU16Data();
+        }
+        final long totalValueCount = (long) planePixelCount * (long) planes.length;
+        if (totalValueCount > (long) Integer.MAX_VALUE) {
+            throw new IOException("Unable to load image data for planes, file size is too big.");
+        }
+
+        Arrays.sort(planes);
+
+        final short[] flatBuffer = (short[]) bufferInputData.getPixelBuffer();
+        int[] destBuffer = new int[(int) totalValueCount];
+        int destOffset = 0;
+        for (final int planeIndex : planes) {
+            final int planeOffset = planeIndex * planePixelCount;
+            copyShortArrayIntoBuffer(flatBuffer, planeOffset, destBuffer, destOffset, planePixelCount);
+            destOffset += planePixelCount;
+        }
+        return destBuffer;
+    }
+
+    @Override
+    public int[] loadAllPlanesU16Data() {
+        final short[] flatBuffer = (short[]) bufferInputData.getPixelBuffer();
+        return TypeConverter.shortArrayToIntArray(flatBuffer);
+    }
+
+    @Override
+    public int[][] loadRowVectors(final int vectorSize, final Range<Integer> planeRange) {
+        return loadRowVectorsImplByValueAt(vectorSize, planeRange);
+    }
+
+    @Override
+    public int[][] loadBlocks(final V2i blockDim, final Range<Integer> planeRange) {
+        return loadBlocksImplByValueAt(blockDim, planeRange);
+    }
+
+    @Override
+    public int[][] loadVoxels(final V3i voxelDim, final Range<Integer> planeRange) throws IOException {
+        return loadVoxelsImplByValueAt(voxelDim, planeRange);
+    }
+}
diff --git a/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java b/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
index 6783ba6959acc41f7844c342e68fc44d746c8c40..b34f67e726a83bfe90f1113fe3570331c2c5076e 100644
--- a/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
+++ b/src/main/java/azgracompress/io/loader/PlaneLoaderFactory.java
@@ -2,6 +2,7 @@ package azgracompress.io.loader;
 
 import azgracompress.io.BufferInputData;
 import azgracompress.io.FileInputData;
+import azgracompress.io.FlatBufferInputData;
 import azgracompress.io.InputData;
 
 public final class PlaneLoaderFactory {
@@ -21,6 +22,8 @@ public final class PlaneLoaderFactory {
                 return new SCIFIOLoader((FileInputData) inputDataInfo);
             case ImageJBufferLoader:
                 return new ImageJBufferLoader((BufferInputData) inputDataInfo);
+            case FlatBufferLoader:
+                return new FlatBufferLoader((FlatBufferInputData) inputDataInfo);
             default:
                 throw new Exception("Unsupported data loader.");
         }