changeset 8:deeb54b231aa

refactor code
author Dennis <denniscmartin@protonmail.com>
date Sun, 30 Oct 2022 17:00:56 +0100
parents a9dd80a69887
children 22cf01362b45
files .github/resources/maze.png .github/resources/sol.png .gitignore .idea/misc.xml CMakeLists.txt README.md algo.c algo.h build.sh main.c mazes/maze1.png mazes/maze2.png mazes/maze3.png resources/maze.png resources/sol.png src/algos.c src/algos.h src/handlers.c src/handlers.h src/main.c src/process.c src/process.h
diffstat 22 files changed, 381 insertions(+), 371 deletions(-) [+]
line wrap: on
line diff
Binary file .github/resources/maze.png has changed
Binary file .github/resources/sol.png has changed
--- a/.gitignore	Sun Oct 16 17:17:15 2022 +0200
+++ b/.gitignore	Sun Oct 30 17:00:56 2022 +0100
@@ -1,4 +1,5 @@
 sols
+mazes
 
 # Created by https://www.toptal.com/developers/gitignore/api/python,c,pycharm,clion,macos
 # Edit at https://www.toptal.com/developers/gitignore?templates=python,c,pycharm,clion,macos
--- a/.idea/misc.xml	Sun Oct 16 17:17:15 2022 +0200
+++ b/.idea/misc.xml	Sun Oct 30 17:00:56 2022 +0100
@@ -3,6 +3,7 @@
   <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
   <component name="CidrRootsConfiguration">
     <excludeRoots>
+      <file path="$PROJECT_DIR$/mazes" />
       <file path="$PROJECT_DIR$/sols" />
     </excludeRoots>
   </component>
--- a/CMakeLists.txt	Sun Oct 16 17:17:15 2022 +0200
+++ b/CMakeLists.txt	Sun Oct 30 17:00:56 2022 +0100
@@ -7,6 +7,6 @@
 
 set(CMAKE_C_STANDARD 99)
 
-add_executable(maze_solver main.c algo.c algo.h)
+add_executable(maze_solver src/main.c src/algos.c src/algos.h src/process.c src/process.h src/handlers.c src/handlers.h)
 
 target_link_libraries(maze_solver png)              # Link libraries
--- a/README.md	Sun Oct 16 17:17:15 2022 +0200
+++ b/README.md	Sun Oct 30 17:00:56 2022 +0100
@@ -13,11 +13,10 @@
 ## Usage
 
 1. Build executable
-2. Make a folder named `mazes` and place the `png` files there.
-3. Make a folder named `sols`. The script place the solutions here.
+2. Make a folder named `sols`. The script place the solutions here.
 
-![maze](resources/maze.png)
-![solution](resources/sol.png)
+![maze](.github/resources/maze.png)
+![solution](.github/resources/sol.png)
 
 ## Resources
 - [Maze generator](https://keesiemeijer.github.io/maze-generator/#generate)
--- a/algo.c	Sun Oct 16 17:17:15 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-//
-// Created by Dennis Concepción Martín on 15/10/22.
-//
-
-#include "algo.h"
-
-int isPath(unsigned x, unsigned y, png_bytep* pRows) {
-    png_byte *pRow = pRows[y];
-    png_byte *pPixel = &pRow[x * 4];
-
-    /*
-     * pPixel[0] -> R
-     * pPixel[1] -> G
-     * pPixel[2] -> B
-     */
-
-    if (pPixel[0] == 255) {
-        pPixel[1] = 0;
-        pPixel[2] = 0;
-
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-
-void wallFollower(png_bytep* pRows, unsigned int width) {
-    unsigned int x = 0;
-    unsigned int y = 1;
-    char direction = 'R';
-
-    isPath(x, y, pRows);
-
-    while (x < width && y < width) {
-
-        if (x == width - 1 && y == width - 2) {
-            break;
-        }
-
-        switch (direction) {  // NOLINT(hicpp-multiway-paths-covered)
-            case 'R':
-
-                // Check if down position is white
-                if (isPath(x, y + 1, pRows)) {
-                    ++y;
-                    direction = 'D';
-                }
-
-                // Check if right position is white
-                else if (isPath(x + 1, y, pRows)) {
-                    ++x;
-                    direction = 'R';
-                }
-
-                // Check if up position is white
-                else if (isPath(x, y - 1, pRows)) {
-                    --y;
-                    direction = 'U';
-                }
-
-                // Turn 180
-                else {
-                    --x;
-                    direction = 'L';
-                }
-
-                break;
-
-            case 'L':
-
-                // Check if up position is white
-                if (isPath(x, y - 1, pRows)) {
-                    --y;
-                    direction = 'U';
-                }
-
-                // Check if left position is white
-                else if (isPath(x - 1, y, pRows)) {
-                    --x;
-                    direction = 'L';
-                }
-
-                // Check if down position is white
-                else if (isPath(x, y + 1, pRows)) {
-                    ++y;
-                    direction = 'D';
-                }
-
-                // Turn 180
-                else {
-                    ++x;
-                    direction = 'R';
-                }
-
-                break;
-
-            case 'U':
-
-                // Check if right position is white
-                if (isPath(x + 1, y, pRows)) {
-                    ++x;
-                    direction = 'R';
-                }
-
-                // Check if up position is white
-                else if (isPath(x, y - 1, pRows)) {
-                    --y;
-                    direction = 'U';
-                }
-
-                // Check if left position is white
-                else if (isPath(x - 1, y, pRows)) {
-                    --x;
-                    direction = 'L';
-                }
-
-                // Turn 180
-                else {
-                    ++y;
-                    direction = 'D';
-                }
-
-                break;
-
-            case 'D':
-
-                // Check if left position is white
-                if (isPath(x - 1, y, pRows)) {
-                    --x;
-                    direction = 'L';
-                }
-
-                // Check if down position is white
-                else if (isPath(x, y + 1, pRows)) {
-                    ++y;
-                    direction = 'D';
-                }
-
-                // Check if right position is white
-                else if (isPath(x + 1, y, pRows)) {
-                    ++x;
-                    direction = 'R';
-                }
-
-                // Turn 180
-                else {
-                    --y;
-                    direction = 'U';
-                }
-
-                break;
-        }
-    }
-}
\ No newline at end of file
--- a/algo.h	Sun Oct 16 17:17:15 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-//
-// Created by Dennis Concepción Martín on 15/10/22.
-//
-
-#ifndef MAZE_SOLVER_ALGO_H
-#define MAZE_SOLVER_ALGO_H
-
-#include <png.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-void wallFollower(png_bytep* pRows, unsigned int width);
-
-#endif //MAZE_SOLVER_ALGO_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build.sh	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+mkdir mazes
+mkdir sols
\ No newline at end of file
--- a/main.c	Sun Oct 16 17:17:15 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-#include "algo.h"
-
-int main(int argc, char* argv[]) {
-    char* unsolvedFilename;
-    char* solvedFilename;
-    int phases;
-    unsigned int width, height;
-
-    clock_t start, end;
-    double cpuTimeUsed;
-
-    FILE* unsolvedFp;
-    png_structp unsolvedPngStruct;
-    png_infop unsolvedPngInfo;
-    png_byte colorType;
-    png_byte bitDepth;
-    png_bytep* pRows;
-
-    FILE* solvedFp;
-    png_structp solvedPngStruct;
-    png_infop solvedPngInfo;
-
-    start = clock();
-
-    if (argc < 2) {
-        printf("Incorrect arguments\n");
-        abort();
-    }
-
-    // Get user arguments
-    unsolvedFilename = argv[1];
-
-    /*
-     * READ FILE
-     */
-
-    // Add path to unsolvedFilename
-    asprintf(&unsolvedFilename, "mazes/%s", unsolvedFilename);
-
-    // Open file
-    unsolvedFp = fopen(unsolvedFilename, "rb");
-
-    if (!unsolvedFp) {
-        printf("Error opening image named %s\n", unsolvedFilename);
-        abort();
-    }
-
-    // Allocate and initialize a unsolvedPngStruct for reading PNG file
-    unsolvedPngStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
-    if (!unsolvedPngStruct) {
-        printf("png_create_read_struct failed\n");
-        abort();
-    }
-
-    // Allocate and initialize a unsolvedPngInfo structure
-    unsolvedPngInfo = png_create_info_struct(unsolvedPngStruct);
-
-    if (!unsolvedPngInfo) {
-        printf("png_create_info_struct failed\n");
-        abort();
-    }
-
-    /*
-     * When libpng encounters an error, it expects to longjmp back to your routine.
-     * Therefore, you will need to call setjmp and pass your png_jmpbuf(unsolvedPngStruct).
-     * More about setjmp -> https://es.wikipedia.org/wiki/Setjmp.h
-     */
-
-    if (setjmp(png_jmpbuf(unsolvedPngStruct))) {
-        printf("Error during init_io\n");
-        abort();
-    }
-
-    png_init_io(unsolvedPngStruct, unsolvedFp);             // Initialize the default input/output functions for the PNG file
-    png_set_sig_bytes(unsolvedPngStruct, 0);        // Set signature bytes
-    png_read_info(unsolvedPngStruct, unsolvedPngInfo);      // Read info
-
-    width = png_get_image_width(unsolvedPngStruct, unsolvedPngInfo);
-    height = png_get_image_height(unsolvedPngStruct, unsolvedPngInfo);
-    colorType = png_get_color_type(unsolvedPngStruct, unsolvedPngInfo);
-    bitDepth = png_get_bit_depth(unsolvedPngStruct, unsolvedPngInfo);
-
-    phases = png_set_interlace_handling(unsolvedPngStruct);
-    png_read_update_info(unsolvedPngStruct, unsolvedPngInfo);
-
-    printf("Image width: %d\n", width);
-    printf("Image height: %d\n", height);
-    printf("Color type: %d\n", colorType);
-    printf("Bit depth: %d\n", bitDepth);
-    printf("Number of phases: %d\n", phases);
-
-    // Read file
-    if (setjmp(png_jmpbuf(unsolvedPngStruct))) {
-        printf("Error during read_image");
-        abort();
-    }
-
-    pRows = (png_bytep*) malloc(sizeof(png_bytep) * height);
-
-    for (int y = 0; y < height; y++) {
-        pRows[y] = (png_byte *) malloc(png_get_rowbytes(unsolvedPngStruct, unsolvedPngInfo));
-    }
-
-    // Read the image into memory
-    png_read_image(unsolvedPngStruct, pRows);
-    fclose(unsolvedFp);
-
-    /*
-     * ALGOS
-     */
-
-    wallFollower(pRows, width);
-
-    /*
-     * WRITE FILE
-     */
-
-    // Add path to unsolvedFilename
-    solvedFilename = argv[1];
-    asprintf(&solvedFilename, "sols/%s", solvedFilename);
-
-    // Open file
-    solvedFp = fopen(solvedFilename, "wb");
-
-    if (!solvedFp) {
-        printf("File %s could not be opened for writing", solvedFilename);
-        abort();
-    }
-
-    // Allocate and initialize a solvedPngStruct for writting PNG file
-    solvedPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
-    if (!solvedPngStruct) {
-        printf("png_create_read_struct failed\n");
-        abort();
-    }
-
-    // Allocate and initialize a unsolvedPngInfo structure
-    solvedPngInfo = png_create_info_struct(solvedPngStruct);
-
-    if (!solvedPngInfo) {
-        printf("png_create_info_struct failed\n");
-        abort();
-    }
-
-    if (setjmp(png_jmpbuf(solvedPngStruct))) {
-        printf("Error during init_io\n");
-        abort();
-    }
-
-    png_init_io(solvedPngStruct, solvedFp);
-
-    // Write header
-    if (setjmp(png_jmpbuf(solvedPngStruct))) {
-        printf("Error writing header");
-        abort();
-    }
-
-    png_set_IHDR(solvedPngStruct, solvedPngInfo, width, height, bitDepth, colorType, PNG_INTERLACE_NONE,
-                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE
-     );
-
-    png_write_info(solvedPngStruct, solvedPngInfo);
-
-    // Write bytes
-    if (setjmp(png_jmpbuf(solvedPngStruct))) {
-        printf("Error writing bytes");
-        abort();
-    }
-
-    png_write_image(solvedPngStruct, pRows);
-
-    // End write
-    if (setjmp(png_jmpbuf(solvedPngStruct))) {
-        printf("Error during end of write");
-        abort();
-    }
-
-    png_write_end(solvedPngStruct, NULL);
-
-    // Cleanup heap allocation
-    for (int y = 0; y < height; y++) {
-        free(pRows[y]);
-    }
-
-    free(pRows);
-    fclose(solvedFp);
-
-    end = clock();
-    cpuTimeUsed = ((double) (end - start)) / CLOCKS_PER_SEC;
-
-    printf("Maze solved in %f seconds\n", cpuTimeUsed);
-
-    return 0;
-}
\ No newline at end of file
Binary file mazes/maze1.png has changed
Binary file mazes/maze2.png has changed
Binary file mazes/maze3.png has changed
Binary file resources/maze.png has changed
Binary file resources/sol.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/algos.c	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,148 @@
+//
+// Created by Dennis Concepción Martín on 15/10/22.
+//
+
+#include "algos.h"
+
+int is_path(unsigned x, unsigned y, png_bytep* pRows) {
+    png_byte *pRow = pRows[y];
+    png_byte *pPixel = &pRow[x * 4];
+
+    if (pPixel[0] == 255) {     // pPixel[0] -> R
+        pPixel[1] = 0;          // pPixel[1] -> G
+        pPixel[2] = 0;          // pPixel[2] -> B
+
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+void wall_follower(png_bytep* pRows, unsigned int width) {
+    unsigned int x = 0;
+    unsigned int y = 1;
+    char direction = 'R';
+
+    is_path(x, y, pRows);
+
+    while (x < width && y < width) {
+
+        if (x == width - 1 && y == width - 2) {
+            break;
+        }
+
+        switch (direction) {  // NOLINT(hicpp-multiway-paths-covered)
+            case 'R':
+
+                // Check if down position is white
+                if (is_path(x, y + 1, pRows)) {
+                    ++y;
+                    direction = 'D';
+                }
+
+                // Check if right position is white
+                else if (is_path(x + 1, y, pRows)) {
+                    ++x;
+                    direction = 'R';
+                }
+
+                // Check if up position is white
+                else if (is_path(x, y - 1, pRows)) {
+                    --y;
+                    direction = 'U';
+                }
+
+                // Turn 180
+                else {
+                    --x;
+                    direction = 'L';
+                }
+
+                break;
+
+            case 'L':
+
+                // Check if up position is white
+                if (is_path(x, y - 1, pRows)) {
+                    --y;
+                    direction = 'U';
+                }
+
+                // Check if left position is white
+                else if (is_path(x - 1, y, pRows)) {
+                    --x;
+                    direction = 'L';
+                }
+
+                // Check if down position is white
+                else if (is_path(x, y + 1, pRows)) {
+                    ++y;
+                    direction = 'D';
+                }
+
+                // Turn 180
+                else {
+                    ++x;
+                    direction = 'R';
+                }
+
+                break;
+
+            case 'U':
+
+                // Check if right position is white
+                if (is_path(x + 1, y, pRows)) {
+                    ++x;
+                    direction = 'R';
+                }
+
+                // Check if up position is white
+                else if (is_path(x, y - 1, pRows)) {
+                    --y;
+                    direction = 'U';
+                }
+
+                // Check if left position is white
+                else if (is_path(x - 1, y, pRows)) {
+                    --x;
+                    direction = 'L';
+                }
+
+                // Turn 180
+                else {
+                    ++y;
+                    direction = 'D';
+                }
+
+                break;
+
+            case 'D':
+
+                // Check if left position is white
+                if (is_path(x - 1, y, pRows)) {
+                    --x;
+                    direction = 'L';
+                }
+
+                // Check if down position is white
+                else if (is_path(x, y + 1, pRows)) {
+                    ++y;
+                    direction = 'D';
+                }
+
+                // Check if right position is white
+                else if (is_path(x + 1, y, pRows)) {
+                    ++x;
+                    direction = 'R';
+                }
+
+                // Turn 180
+                else {
+                    --y;
+                    direction = 'U';
+                }
+
+                break;
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/algos.h	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,12 @@
+//
+// Created by Dennis Concepción Martín on 15/10/22.
+//
+
+#ifndef MAZE_SOLVER_ALGOS_H
+#define MAZE_SOLVER_ALGOS_H
+
+#include <png.h>
+
+void wall_follower(png_bytep* pRows, unsigned int width);
+
+#endif //MAZE_SOLVER_ALGOS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/handlers.c	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,10 @@
+//
+// Created by Dennis Concepción Martín on 18/10/22.
+//
+
+#include "handlers.h"
+
+void error() {
+    perror("Error: ");
+    exit(EXIT_FAILURE);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/handlers.h	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,13 @@
+//
+// Created by Dennis Concepción Martín on 18/10/22.
+//
+
+#ifndef MAZE_SOLVER_HANDLERS_H
+#define MAZE_SOLVER_HANDLERS_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+void error();
+
+#endif //MAZE_SOLVER_HANDLERS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.c	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,28 @@
+#include <time.h>
+#include "process.h"
+#include "algos.h"
+
+int main(int argc, char* argv[]) {
+    if (argc < 2) {
+        printf("Incorrect arguments\n");
+        error();
+    }
+
+    char* filename = argv[1];
+    struct PngInfo png_info = read_png(filename);
+
+    printf("Filename: %s\n", png_info.filename);
+    printf("Width: %d\n", png_info.width);
+    printf("Height: %d\n", png_info.height);
+
+    clock_t start = clock();
+    wall_follower(png_info.rows, png_info.width);
+    clock_t end = clock();
+
+    double time_taken = ((double) (end - start)) / CLOCKS_PER_SEC;
+    printf("Algorithm duration: %f seconds\n", time_taken);
+
+    write_png(png_info);
+
+    return 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/process.c	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,139 @@
+//
+// Created by Dennis Concepción Martín on 18/10/22.
+//
+
+#include "process.h"
+
+struct PngInfo read_png(char* filename) {
+    struct PngInfo png_info;
+    png_info.filename = filename;
+
+    asprintf(&filename, "mazes/%s", filename);
+    FILE* fp = fopen(filename, "rb");
+
+    if (!fp) {
+        error();
+    }
+
+    // Allocate and initialize read struct
+    png_structp read_struct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+    if (!read_struct) {
+        error();
+    }
+
+    // Allocate and initialize info struct
+    png_infop info_struct = png_create_info_struct(read_struct);
+
+    if (!info_struct) {
+        error();
+    }
+
+    /*
+     * When libpng encounters an error, it expects to longjmp back to your routine.
+     * Therefore, you will need to call setjmp and pass your png_jmpbuf(unsolvedPngStruct).
+     * More about setjmp -> https://es.wikipedia.org/wiki/Setjmp.h
+     */
+
+    if (setjmp(png_jmpbuf(read_struct))) {
+        error();
+    }
+
+    png_init_io(read_struct, fp);               // Init default input/output functions
+    png_set_sig_bytes(read_struct, 0);          // Set signature bytes
+    png_read_info(read_struct, info_struct);    // Read info
+
+    // Set struct variables
+    png_info.width = png_get_image_width(read_struct, info_struct);
+    png_info.height = png_get_image_height(read_struct, info_struct);
+    png_info.byte_depth = png_get_bit_depth(read_struct, info_struct);
+    png_info.color_type = png_get_color_type(read_struct, info_struct);
+
+    png_read_update_info(read_struct, info_struct);
+
+    // Read file
+    if (setjmp(png_jmpbuf(read_struct))) {
+        error();
+    }
+
+    // Allocate memory dynamically
+    png_bytep* rows = (png_bytep*) malloc(sizeof(png_bytep) * png_info.height);
+    png_info.rows = rows;
+
+    for (int y = 0; y < png_info.height; y++) {
+        rows[y] = (png_byte *) malloc(png_get_rowbytes(read_struct, info_struct));
+    }
+
+    // Read image into memory
+    png_read_image(read_struct, rows);
+    fclose(fp);
+
+    return png_info;
+}
+
+void write_png(struct PngInfo png_info) {
+    char* solved_filename = png_info.filename;
+    asprintf(&solved_filename, "sols/%s", solved_filename);
+    FILE* fp = fopen(solved_filename, "wb");
+
+    if (!fp) {
+        error();
+    }
+
+    // Allocate and initialize write struct
+    png_structp write_struct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+    if (!write_struct) {
+        error();
+    }
+
+    // Allocate and initialize infor struct
+    png_infop info_struct = png_create_info_struct(write_struct);
+
+    if (!info_struct) {
+        error();
+    }
+
+    if (setjmp(png_jmpbuf(write_struct))) {
+        error();
+    }
+
+    png_init_io(write_struct, fp);
+
+    // Write header
+    if (setjmp(png_jmpbuf(write_struct))) {
+        printf("Error writing header");
+        abort();
+    }
+
+    png_set_IHDR(
+            write_struct, info_struct, png_info.width, png_info.height, png_info.byte_depth, png_info.color_type,
+            PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE
+    );
+
+    png_write_info(write_struct, info_struct);
+
+    // Write bytes
+    if (setjmp(png_jmpbuf(write_struct))) {
+        printf("Error writing bytes");
+        abort();
+    }
+
+    png_write_image(write_struct, png_info.rows);
+
+    // End write
+    if (setjmp(png_jmpbuf(write_struct))) {
+        printf("Error during end of write");
+        abort();
+    }
+
+    png_write_end(write_struct, NULL);
+
+    // Cleanup heap allocation
+    for (int y = 0; y < png_info.height; y++) {
+        free(png_info.rows[y]);
+    }
+
+    free(png_info.rows);
+    fclose(fp);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/process.h	Sun Oct 30 17:00:56 2022 +0100
@@ -0,0 +1,21 @@
+//
+// Created by Dennis Concepción Martín on 18/10/22.
+//
+
+#ifndef MAZE_SOLVER_PROCESS_H
+#define MAZE_SOLVER_PROCESS_H
+
+#include <png.h>
+#include "handlers.h"
+
+struct PngInfo {
+    char* filename;
+    unsigned int width, height;
+    png_bytep* rows;
+    png_byte byte_depth, color_type;
+};
+
+struct PngInfo read_png(char* filename);
+void write_png(struct PngInfo);
+
+#endif //MAZE_SOLVER_PROCESS_H