diff --git a/src/img2sparse.c b/src/img2sparse.c
index caef226f22a250408d312236f690362a12eded4a..77e3316b2530ac49ce210e156c5032d97c365837 100644
--- a/src/img2sparse.c
+++ b/src/img2sparse.c
@@ -32,13 +32,134 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     INCLUDE
 ==============================================================================*/
 // C Standard Library
+#include <assert.h>
 #include <stdlib.h> // EXIT_SUCCESS
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>   // uint32_t, UINT32_MAX
 // Internal
+#include "file_io.h"
+#include "log.h"
 #include "sparse.h"
+/*==============================================================================
+    STATIC
+==============================================================================*/
+static struct Logger s_logger = {
+    .level_flag = LOG_LEVEL_ALL,
+    .output     = LOG_OUTPUT_STDERR
+};
 /*==============================================================================
     MAIN
 ==============================================================================*/
 int main(int argc, char * argv[])
 {
+    /*struct Sparse * sparse = Sparse_Create(argv[1], "r");
+    Sparse_ReadImage(sparse);
+    int fd = FIO_Open(args->sparse_path, "w");
+    if(fd != -1) {
+        Sparse_Write(sparse, fd);
+        FIO_Close(fd);
+    } else {
+        Log_Fatal(&s_logger, "FIO_Open(%s, \"w\") : %s\n",args->sparse_path, strerror(errno));
+        exit(-1);
+    }
+    Sparse_Close(&sparse);*/
+
+    int fd_in = FIO_Open(argv[1], "r");
+    if(fd_in != -1) {
+        size_t img_size = FIO_GetSize(fd_in);
+        char * buffer = malloc(img_size);
+        if(buffer != NULL) {
+            size_t bytes_read = FIO_Read(fd_in, buffer, img_size);
+            if(bytes_read == img_size) {
+                size_t block_size = Sparse_GuessBlockSize(img_size);
+                block_size = 1024;
+                if(block_size != 0) {
+                    struct Sparse * sparse = Sparse_Create(block_size, img_size);
+                    size_t chunk_count = 0;
+                    enum Sparse_ChunkType prev_type = CHUNK_TYPE_NONE;
+                    // Need to be allocated once before being able to call realloc()
+                    sparse->chunks = malloc(sizeof(*sparse->chunks));
+                    for(size_t i = 0; i < sparse->header.block_count; i++) {
+                        enum Sparse_ChunkType curr_type = CHUNK_TYPE_NONE;
+                        size_t block_offset = i * block_size;
+                        size_t sparse_data_size = 0;
+                        for(size_t j = 1; j < sparse->header.block_size; j++) {
+                            if(buffer[block_offset] != buffer[block_offset + j]) {
+                                curr_type = CHUNK_TYPE_RAW;
+                                break;
+                            }
+                        }
+                        if(curr_type != CHUNK_TYPE_RAW) {
+                            sparse_data_size = 4;
+                            //printf("Block %zu = raw\n", i);
+                            if(buffer[block_offset] == 0) {
+                                //printf("Block %zu = dc\n", i);
+                                curr_type = CHUNK_TYPE_DONT_CARE;
+                            } else {
+                                //printf("Block %zu = fill\n", i);
+                                curr_type = CHUNK_TYPE_FILL;
+                            }
+                        }
+                        if(prev_type != curr_type) {
+                            sparse->chunks = realloc(sparse->chunks, sizeof(*sparse->chunks) * (chunk_count + 1));
+                            sparse->chunks[chunk_count].type = curr_type;
+                            sparse->chunks[chunk_count].size = sparse_data_size;
+                            sparse->chunks[chunk_count].data = buffer + (i * block_size);
+                            chunk_count++;
+                        }
+                        prev_type = curr_type;
+                    }
+                    sparse->header.chunk_count = chunk_count;
+                    int fd_out = FIO_Open(argv[2], "w");
+                    if(fd_out != -1) {
+                        FIO_Write(fd_out, &sparse->header, sizeof(sparse->header));
+                        for(size_t i = 0; i < chunk_count; i++) {
+                            FIO_Write(fd_out, &(sparse->chunks[i].type), sizeof(uint16_t));
+                            FIO_Write(fd_out, &((uint16_t){0}), sizeof(uint16_t));
+                            size_t img_data_size = (size_t)sparse->chunks[i+1].data - (size_t)sparse->chunks[i].data;
+                            sparse->chunks[i].block_count = img_data_size / 1024;
+                            if(sparse->chunks[i].type == CHUNK_TYPE_RAW) {
+                                sparse->chunks[i].size = img_data_size;
+                            }
+                            if(i == (chunk_count-1)) {
+                                img_data_size = (size_t)(&buffer[img_size]) - (size_t)sparse->chunks[i].data;
+                                printf("last data size = %zu\n", img_data_size);
+                                sparse->chunks[i].block_count = img_data_size / 1024;
+                            }
+                            printf("block count %zu\n", sparse->chunks[i].block_count);
+                            FIO_Write(fd_out, &(sparse->chunks[i].block_count), sizeof(uint32_t));
+                            FIO_Write(fd_out, &((uint32_t){sparse->chunks[i].size+12}), sizeof(uint32_t));
+                            printf("%zu - %zu = %zu\n", (size_t)sparse->chunks[i+1].data, (size_t)sparse->chunks[i].data, sparse->chunks[i].size);
+                            FIO_Write(fd_out, sparse->chunks[i].data, sparse->chunks[i].size);
+                        }
+                        Sparse_DumpInfo(sparse);
+                        FIO_Close(fd_out);
+                    } else {
+                        Log_Fatal(&s_logger, "FIO_Open(%s, \"w\") : %s\n",argv[2], strerror(errno));
+                        exit(-1);
+                    }
+                    /*printf("chunk_count = %zu\n", chunk_count);
+                    for(size_t i = 0; i < chunk_count; i++) {
+                        printf("%zu\t", sparse->chunks[i].type);
+                        printf("%p\n", sparse->chunks[i].data);
+                    }*/
+                } else {
+                    Log_Fatal(&s_logger, "Invalid image size!\n", fd_in, strerror(errno));
+                    exit(-1);
+                }
+            } else {
+                Log_Fatal(&s_logger, "FIO_Read(%d) failed! %s\n", fd_in, strerror(errno));
+                    exit(-1);
+            }
+            free(buffer);
+        }
+        FIO_Close(fd_in);
+    } else {
+        Log_Fatal(&s_logger, "FIO_Open(%s, \"r\") failed! %s\n",
+            argv[1], strerror(errno));
+        exit(-1);
+    }
     return EXIT_SUCCESS;
 }