diff options
-rw-r--r-- | Makefile | 60 | ||||
-rw-r--r-- | include/snippets/raylib_block.c | 93 | ||||
-rw-r--r-- | lib/algo/avl_tree.c (renamed from src/lib/algo/avl_tree.c) | 0 | ||||
-rw-r--r-- | lib/algo/flood_fill.c (renamed from src/lib/algo/flood_fill.c) | 0 | ||||
-rw-r--r-- | lib/color.c (renamed from src/lib/color.c) | 0 | ||||
-rw-r--r-- | lib/dir.c (renamed from src/lib/dir.c) | 0 | ||||
-rw-r--r-- | lib/file.c (renamed from src/lib/file.c) | 0 | ||||
-rw-r--r-- | lib/lib.c (renamed from src/lib/lib.c) | 0 | ||||
-rw-r--r-- | lib/png.c (renamed from src/lib/png.c) | 0 | ||||
-rw-r--r-- | lib/seg/mask_data.c (renamed from src/lib/seg/mask_data.c) | 0 | ||||
-rw-r--r-- | lib/seg/util.c (renamed from src/lib/seg/util.c) | 13 | ||||
-rw-r--r-- | lib/time.c (renamed from src/lib/time.c) | 0 | ||||
-rwxr-xr-x | run.sh | 2 | ||||
-rw-r--r-- | src/prog.c (renamed from src/main.c) | 55 | ||||
-rw-r--r-- | src/visual.c | 311 |
15 files changed, 390 insertions, 144 deletions
@@ -1,23 +1,49 @@ PKGS=libtiff-4 libpng DEFINES= -EXE=prog BUILD_DIR=build/ -OBJ_DIR=$(BUILD_DIR)obj/ -SRC_DIR=src/ INC_DIR=include/ -SRCS=$(shell find $(SRC_DIR) -iname \*.c) -OBJS_sub=$(subst $(SRC_DIR),$(OBJ_DIR),$(SRCS)) -OBJS=$(OBJS_sub:.c=.o) -OBJ_DIRS_sub=$(shell find $(SRC_DIR) -type d) -OBJ_DIRS=$(subst $(SRC_DIR),$(OBJ_DIR),$(OBJ_DIRS_sub)) + +# Source files +SRC_DIR=src/ +SRC_OBJ_DIR=$(BUILD_DIR)obj/$(SRC_DIR) +SRC_SRCS=$(shell find $(SRC_DIR) -iname \*.c) +SRC_OBJS_sub=$(subst $(SRC_DIR),$(SRC_OBJ_DIR),$(SRC_SRCS)) +SRC_OBJS=$(SRC_OBJS_sub:.c=.o) +SRC_OBJ_DIRS_sub=$(shell find $(SRC_DIR) -type d) +SRC_OBJ_DIRS=$(subst $(SRC_DIR),$(SRC_OBJ_DIR),$(SRC_OBJ_DIRS_sub)) + +# Library files +LIB_DIR=lib/ +LIB_OBJ_DIR=$(BUILD_DIR)obj/$(LIB_DIR) +LIB_SRCS=$(shell find $(LIB_DIR) -iname \*.c) +LIB_OBJS_sub=$(subst $(LIB_DIR),$(LIB_OBJ_DIR),$(LIB_SRCS)) +LIB_OBJS=$(LIB_OBJS_sub:.c=.o) +LIB_OBJ_DIRS_sub=$(shell find $(LIB_DIR) -type d) +LIB_OBJ_DIRS=$(subst $(LIB_DIR),$(LIB_OBJ_DIR),$(LIB_OBJ_DIRS_sub)) + +# Programs +PROG_DIR= +PROG_OUT_DIR=$(BUILD_DIR)$(PROG_DIR) +PROG_SRCS=$(shell find $(SRC_DIR) -iname \*.c) +PROG_OBJS=$(PROG_SRCS:.c=.o) +PROG_DIRS_sub=$(shell find $(SRC_DIR) -type d) +PROG_DIRS=$(subst $(SRC_DIR),$(PROG_OUT_DIR),$(PROG_DIRS_sub)) +PROGS_sub=$(subst $(SRC_DIR),$(PROG_OUT_DIR),$(PROG_SRCS)) +PROGS=$(PROGS_sub:.c=) # Include raylib if we want a visual experience ifdef RAYLIB -$(info "Visual Experience Selected") +$(info Visual Experience Selected) PKGS+=raylib DEFINES+=-DVISUAL endif +# Dump AVL tree info? +ifdef AVL_INFO +$(info Including AVL Dump) +DEFINES+=-DAVL_INFO +endif + ifeq ($(shell uname -s),Linux) PKGCONF=pkgconf endif @@ -38,21 +64,21 @@ default: clean build .PHONY: clean build run -build: $(BUILD_DIR)$(EXE) +build: $(PROGS) -$(BUILD_DIR)$(EXE): $(OBJS) +$(BUILD_DIR)$(PROG_DIR)%: $(SRC_OBJ_DIR)%.o $(LIB_OBJS) @echo LD --\> $@ @gcc -o $@ $(LDFLAGS) $^ -$(OBJ_DIR)%.o: $(SRC_DIR)%.c +$(SRC_OBJ_DIR)%.o: $(SRC_DIR)%.c + @echo CC $< --\> $@ + @gcc -o $@ $(CFLAGS) -c $< + +$(LIB_OBJ_DIR)%.o: $(LIB_DIR)%.c @echo CC $< --\> $@ @gcc -o $@ $(CFLAGS) -c $< clean: @echo Cleaning build files... @-rm -rf $(OBJ_DIR) $(BUILD_DIR) - @mkdir -p $(OBJ_DIR) $(BUILD_DIR) $(OBJ_DIRS) - -run: $(BUILD_DIR)$(EXE) - @echo Executing... - @./$(BUILD_DIR)$(EXE) + @mkdir -p $(BUILD_DIR) $(SRC_OBJ_DIRS) $(LIB_OBJ_DIRS) $(PROG_DIRS) diff --git a/include/snippets/raylib_block.c b/include/snippets/raylib_block.c deleted file mode 100644 index ef81fd2..0000000 --- a/include/snippets/raylib_block.c +++ /dev/null @@ -1,93 +0,0 @@ - //----------------------------------------------- - //-RAYLIB-INIT----------------------------------- - //----------------------------------------------- - SetTraceLogLevel(LOG_ERROR); - SetConfigFlags(FLAG_WINDOW_RESIZABLE); - const char* gui_title = "Image Manip - Useful for segmentations!"; - InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, gui_title); - - //----------------------------------------------- - // (When treating this as RGBA, last bits should ensure opaque) - // This assumes 4096 (2^12) > labels - for (size_t y = 0; y < height; y++) { - for (size_t x = 0; x < width; x++) { - /// RGBA channels: Move labels to RGB - masks[x + y*width] <<= 4; - masks[x + y*width] |= 0x000F; - } - } - //----------------------------------------------- - - //----------------------------------------------- - //-RAYLIB-IMAGE-STRUCTURING---------------------- - //----------------------------------------------- - Image RaylibImage; - RaylibImage.width = width; - RaylibImage.height = height; - RaylibImage.mipmaps = 1; - // Use Contiguous Labels - RaylibImage.data = masks; - RaylibImage.format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4; - //----------------------------------------------- - - // Image to a Texture - Texture2D RaylibTexture = LoadTextureFromImage(RaylibImage); - - // Scale the image to the viewport - /// Source Rectangle: Original Size - Rectangle sourceRec = { 0.0f, 0.0f, (float)width, (float)height }; - /// Destination Rectangle: Transformed Size - Rectangle destRec = { 0.0f, 0.0f, (float)SCREEN_WIDTH, (float)(SCREEN_HEIGHT-OFFSET) }; - /// Location to begin drawing - Vector2 origin = { (float)0, (float)-OFFSET }; - - // Raylib boilerplate - SetTargetFPS(60); - Camera2D camera = { 0 }; - camera.zoom = 1.0f; - - // GUI Loop - while (!WindowShouldClose()) { - //----------------------------------------------- - //-DRAWING--------------------------------------- - //----------------------------------------------- - BeginDrawing(); - ClearBackground(RAYWHITE); - BeginMode2D(camera); - EndMode2D(); - DrawText("Image Manip", 0, 0, OFFSET, DARKGRAY); - DrawTexturePro(RaylibTexture, sourceRec, destRec, origin, (float)0, - RAYWHITE); - /* - uint32_t x = 0x49, y = 0x4A; - uint32_t dx = 0x69 - x, dy = 0x6E - y; - x = (SCREEN_WIDTH*x)/width; - y = SCREEN_HEIGHT-((SCREEN_HEIGHT-OFFSET)*y)/height; - dx = (SCREEN_WIDTH*dx)/width; - dy = SCREEN_HEIGHT-((SCREEN_HEIGHT-OFFSET)*dy)/height; - DrawRectangleGradientH(x, y, dx, dy, BLUE, PURPLE); - */ - EndDrawing(); - //----------------------------------------------- - } - - //----------------------------------------------- - //-SAVE-MASK-AS-BINARY-AND-PNG------------------- - //----------------------------------------------- - if (masks != NULL) { - for (size_t y = 0; y < height; y++) { - for (size_t x = 0; x < width; x++) { - /// Restore labels from RGBA - masks[x + y*width] &= 0xFFF0; - masks[x + y*width] >>= 4; - } - } - struct bitmap_t* bitmap = uint16_to_bitmap(masks, width, height); - if (bitmap != NULL) { - save_png(bitmap, png_file); - free(bitmap); - } - write_array(bin_file, masks, width*height*sizeof(uint16_t)); - free(masks); - } - CloseWindow(); diff --git a/src/lib/algo/avl_tree.c b/lib/algo/avl_tree.c index db4fa4b..db4fa4b 100644 --- a/src/lib/algo/avl_tree.c +++ b/lib/algo/avl_tree.c diff --git a/src/lib/algo/flood_fill.c b/lib/algo/flood_fill.c index 62db658..62db658 100644 --- a/src/lib/algo/flood_fill.c +++ b/lib/algo/flood_fill.c diff --git a/src/lib/color.c b/lib/color.c index 902a93d..902a93d 100644 --- a/src/lib/color.c +++ b/lib/color.c diff --git a/src/lib/dir.c b/lib/dir.c index be2a2ac..be2a2ac 100644 --- a/src/lib/dir.c +++ b/lib/dir.c diff --git a/src/lib/file.c b/lib/file.c index b6ec1d0..b6ec1d0 100644 --- a/src/lib/file.c +++ b/lib/file.c diff --git a/src/lib/lib.c b/lib/lib.c index c1f26fc..c1f26fc 100644 --- a/src/lib/lib.c +++ b/lib/lib.c diff --git a/src/lib/png.c b/lib/png.c index d12a765..d12a765 100644 --- a/src/lib/png.c +++ b/lib/png.c diff --git a/src/lib/seg/mask_data.c b/lib/seg/mask_data.c index 8c4b037..8c4b037 100644 --- a/src/lib/seg/mask_data.c +++ b/lib/seg/mask_data.c diff --git a/src/lib/seg/util.c b/lib/seg/util.c index 8a5f5e5..677e8f5 100644 --- a/src/lib/seg/util.c +++ b/lib/seg/util.c @@ -115,39 +115,36 @@ void dilate(uint16_t** mask, uint32_t width, uint32_t height) uint16_t* _erode(uint16_t* mask, uint32_t width, uint32_t height) { uint16_t *new_mask = (uint16_t*)calloc(width*height,sizeof(uint16_t)); + memcpy(new_mask, mask, width*height*sizeof(uint16_t)); for (size_t y = 0; y < height; y++) { for (size_t x = 0; x < width; x++) { size_t current_position = xy_to_coord(x, y, width, height); - if (mask[current_position] != 0) { - new_mask[current_position] = mask[current_position]; - continue; - } size_t proposed_position; if (x != 0) { proposed_position = xy_to_coord(x-1, y, width, height); if (mask[proposed_position] == 0) { - new_mask[current_position] = mask[proposed_position]; + new_mask[current_position] = 0; continue; } } if ((x+1) != width) { proposed_position = xy_to_coord(x+1, y, width, height); if (mask[proposed_position] == 0) { - new_mask[current_position] = mask[proposed_position]; + new_mask[current_position] = 0; continue; } } if (y != 0) { proposed_position = xy_to_coord(x, y-1, width, height); if (mask[proposed_position] == 0) { - new_mask[current_position] = mask[proposed_position]; + new_mask[current_position] = 0; continue; } } if ((y+1) != height) { proposed_position = xy_to_coord(x, y+1, width, height); if (mask[proposed_position] == 0) { - new_mask[current_position] = mask[proposed_position]; + new_mask[current_position] = 0; continue; } } diff --git a/src/lib/time.c b/lib/time.c index 085ef80..085ef80 100644 --- a/src/lib/time.c +++ b/lib/time.c @@ -1,4 +1,4 @@ #!/bin/sh SOURCE="$1" mkdir -p output/${SOURCE} -./build/prog -s -d data/${SOURCE} -b output/${SOURCE}/${SOURCE}.bin -p output/${SOURCE}/${SOURCE}.png +./build/prog -s -n 8 -d data/${SOURCE} -b output/${SOURCE}/${SOURCE}.bin -p output/${SOURCE}/${SOURCE}.png @@ -2,10 +2,6 @@ #include <stdlib.h> #include <unistd.h> -#ifdef VISUAL -#include <raylib.h> -#endif - #include <lib/lib.h> #include <lib/png.h> #include <lib/bool.h> @@ -19,28 +15,30 @@ #include <lib/seg/util.h> #include <lib/seg/mask_data.h> -#define OFFSET 16 - -#define N_DILATIONS 10 - -#define MIN_AREA 500 -#define MIN_PERIMETER 0 - int main(int argc, char** argv) { char opt; char* directory = NULL; char* png_file = "../out.png"; char* bin_file = "../out.bin"; + size_t closeup_pixel_count = 10; + size_t min_area = 500; + size_t min_perimeter = 0; bool_t silent = FALSE; //----------------------------------------------- //-GET-COMMAND-LINE-ARGUMENTS-------------------- //----------------------------------------------- - while ((opt = getopt(argc, argv, "d:b:p:s")) != -1) { + while ((opt = getopt(argc, argv, "d:b:p:n:sA:P:")) != -1) { switch (opt) { case 's': silent = TRUE; break; + case 'A': + min_area = atoi(optarg); + break; + case 'P': + min_perimeter = atoi(optarg); + break; case 'd': if (!silent) { printf("Parse Directory: %s\n", optarg); @@ -59,6 +57,12 @@ int main(int argc, char** argv) } png_file = optarg; break; + case 'n': + if (!silent) { + printf("Closeup Size: %d\n", atoi(optarg)); + } + closeup_pixel_count = atoi(optarg); + break; case ':': if (!silent) { printf("Option requires value\n"); @@ -77,7 +81,6 @@ int main(int argc, char** argv) } } TIME(ts_g_start); - struct AVLNode* root = NULL; //----------------------------------------------- //-PROCESS-FILES-IN-DIRECTORY-------------------- //----------------------------------------------- @@ -111,12 +114,18 @@ int main(int argc, char** argv) if (!silent) { printf("Loading %s...\n", fpath); } + //----------------------------------------------- + //-PROCESS-TIFF-TO-LABELS------------------------ + //----------------------------------------------- uint16_t *file_labels = tif_to_labels(fpath, &width, &height, &starting_label); if (file_labels == NULL) { free(fpath); free(file_list[index]); continue; } + //----------------------------------------------- + //-COMBINE-LABELS-TO-GLOBAL-MASK----------------- + //----------------------------------------------- masks = combine_masks(masks, file_labels, width, height); free(file_labels); free(fpath); @@ -139,11 +148,11 @@ int main(int argc, char** argv) printf("%u labels found\n", starting_label-1); printf("Mask dimensions: %u %u\n", width, height); } - TIME(ts_filter_start); //----------------------------------------------- //-FILTER-SMALL-REGIONS-OUT---------------------- //----------------------------------------------- - filter_small_masks(masks, width, height, MIN_AREA, MIN_PERIMETER); + TIME(ts_filter_start); + filter_small_masks(masks, width, height, min_area, min_perimeter); TIME(ts_filter_end); if (!silent) { printf("Removing small labels took %f ms\n", 1000*diff_time(&ts_filter_end, &ts_filter_start)); @@ -158,36 +167,33 @@ int main(int argc, char** argv) printf("%u remaining labels found\n", starting_label-1); printf("Mask dimensions: %u %u\n", width, height); } +#ifdef AVL_INFO //----------------------------------------------- //-OPTIONAL:------------------------------------- //-GET-MASK-META-INFORMATION--------------------- //----------------------------------------------- + struct AVLNode* root = NULL; root = get_mask_data(masks, width, height); -#ifdef AVL_INFO if (!silent) { printf("Inorder traversal of AVL tree: "); print_label(root); printf("\n"); } -#endif free_avl_tree_nodes(root); - - TIME(ts_start); +#endif //----------------------------------------------- //-CLOSE-UP-SMALL-GAPS-BETWEEN-REGIONS----------- //----------------------------------------------- - closeup(&masks, width, height, N_DILATIONS); + TIME(ts_start); + closeup(&masks, width, height, closeup_pixel_count); TIME(ts_end); if (!silent) { - printf("Closing up took %f ms\n", 1000*diff_time(&ts_end, &ts_start)); + printf("Closing (%lu) up took %f ms\n", closeup_pixel_count, 1000*diff_time(&ts_end, &ts_start)); } //----------------------------------------------- //-END-OF-PROCESSING----------------------------- //----------------------------------------------- -#ifdef VISUAL -#include <snippets/raylib_block.c> -#else //----------------------------------------------- //-SAVE-MASK-AS-BINARY-AND-PNG------------------- //----------------------------------------------- @@ -200,7 +206,6 @@ int main(int argc, char** argv) write_array(bin_file, masks, width*height*sizeof(uint16_t)); free(masks); } -#endif TIME(ts_g_end); if (!silent) { printf("Finished in %f ms\n", 1000*diff_time(&ts_g_end, &ts_g_start)); diff --git a/src/visual.c b/src/visual.c new file mode 100644 index 0000000..ac6f63d --- /dev/null +++ b/src/visual.c @@ -0,0 +1,311 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#ifdef VISUAL +#include <raylib.h> +#endif + +#include <lib/lib.h> +#include <lib/png.h> +#include <lib/bool.h> +#include <lib/monad.h> +#include <lib/dir.h> +#include <lib/file.h> +#include <lib/time.h> +#include <lib/color.h> +#include <lib/algo/flood_fill.h> +#include <lib/algo/avl_tree.h> +#include <lib/seg/util.h> +#include <lib/seg/mask_data.h> + +#define OFFSET 16 + +#define MIN_AREA 500 +#define MIN_PERIMETER 0 + +int main(int argc, char** argv) +{ + char opt; + char* directory = NULL; + char* png_file = "../out.png"; + char* bin_file = "../out.bin"; + size_t closeup_pixel_count = 10; + bool_t silent = FALSE; + //----------------------------------------------- + //-GET-COMMAND-LINE-ARGUMENTS-------------------- + //----------------------------------------------- + while ((opt = getopt(argc, argv, "d:b:p:n:s")) != -1) { + switch (opt) { + case 's': + silent = TRUE; + break; + case 'd': + if (!silent) { + printf("Parse Directory: %s\n", optarg); + } + directory = optarg; + break; + case 'b': + if (!silent) { + printf("Bin File: %s\n", optarg); + } + bin_file = optarg; + break; + case 'p': + if (!silent) { + printf("PNG File: %s\n", optarg); + } + png_file = optarg; + break; + case 'n': + if (!silent) { + printf("Closeup Size: %d\n", atoi(optarg)); + } + closeup_pixel_count = atoi(optarg); + break; + case ':': + if (!silent) { + printf("Option requires value\n"); + } + break; + case '?': + if (!silent) { + printf("Unknown option: %c\n", optopt); + } + break; + } + } + if (!silent) { + for (;optind < argc; optind++) { + printf("Extra arguments: %s\n", argv[optind]); + } + } + TIME(ts_g_start); + //----------------------------------------------- + //-PROCESS-FILES-IN-DIRECTORY-------------------- + //----------------------------------------------- + char** file_list = NULL; + uint32_t width, height; + uint16_t starting_label = 1; + uint16_t *masks = NULL; + // Expect a directory to be passed as the first argument + if (directory != NULL) { + // Ensure the directory exists + if (is_directory(directory)) { + // List files in the ddirectory + file_list = list_directory(directory); + if (file_list != NULL) { + for (size_t index = 0; file_list[index] != NULL; index++) { + char* fname = file_list[index]; + if (is_tif_ext(fname) == FALSE) { + free(file_list[index]); + continue; + } + // If we have a tiff file + // 1. Convert to labels + // 2. Find contiguous regions + // 3. Combine with current total mask + // 4. Free up allocations made in this process + char* fpath = full_path(directory, fname); + if (fpath == NULL) { + free(file_list[index]); + continue; + } + if (!silent) { + printf("Loading %s...\n", fpath); + } + //----------------------------------------------- + //-PROCESS-TIFF-TO-LABELS------------------------ + //----------------------------------------------- + uint16_t *file_labels = tif_to_labels(fpath, &width, &height, &starting_label); + if (file_labels == NULL) { + free(fpath); + free(file_list[index]); + continue; + } + //----------------------------------------------- + //-COMBINE-LABELS-TO-GLOBAL-MASK----------------- + //----------------------------------------------- + masks = combine_masks(masks, file_labels, width, height); + free(file_labels); + free(fpath); + free(file_list[index]); + } + free(file_list); + } + } + } + if (masks == NULL) { + fprintf(stderr, "No masks found!\n"); + return 1; + } + + //----------------------------------------------- + //-FIND-CONTIGUOUS-REGIONS----------------------- + //----------------------------------------------- + reduce_contiguous_regions(&masks, width, height, &starting_label); + if (!silent) { + printf("%u labels found\n", starting_label-1); + printf("Mask dimensions: %u %u\n", width, height); + } + //----------------------------------------------- + //-FILTER-SMALL-REGIONS-OUT---------------------- + //----------------------------------------------- + TIME(ts_filter_start); + filter_small_masks(masks, width, height, MIN_AREA, MIN_PERIMETER); + TIME(ts_filter_end); + if (!silent) { + printf("Removing small labels took %f ms\n", 1000*diff_time(&ts_filter_end, &ts_filter_start)); + } + //----------------------------------------------- + //-FIND-CONTIGUOUS-REGIONS----------------------- + //----------------------------------------------- + //--to-make-labels-span-1-to-n------------------- + //----------------------------------------------- + reduce_contiguous_regions(&masks, width, height, &starting_label); + if (!silent) { + printf("%u remaining labels found\n", starting_label-1); + printf("Mask dimensions: %u %u\n", width, height); + } +#ifdef AVL_INFO + //----------------------------------------------- + //-OPTIONAL:------------------------------------- + //-GET-MASK-META-INFORMATION--------------------- + //----------------------------------------------- + struct AVLNode* root = NULL; + root = get_mask_data(masks, width, height); + if (!silent) { + printf("Inorder traversal of AVL tree: "); + print_label(root); + printf("\n"); + } + free_avl_tree_nodes(root); +#endif + //----------------------------------------------- + //-CLOSE-UP-SMALL-GAPS-BETWEEN-REGIONS----------- + //----------------------------------------------- + TIME(ts_start); + closeup(&masks, width, height, closeup_pixel_count); + TIME(ts_end); + if (!silent) { + printf("Closing (%lu) up took %f ms\n", closeup_pixel_count, 1000*diff_time(&ts_end, &ts_start)); + } + //----------------------------------------------- + //-END-OF-PROCESSING----------------------------- + //----------------------------------------------- + +#ifdef VISUAL + //----------------------------------------------- + //-RAYLIB-INIT----------------------------------- + //----------------------------------------------- + SetTraceLogLevel(LOG_ERROR); + SetConfigFlags(FLAG_WINDOW_RESIZABLE); + const char* gui_title = "Image Manip - Useful for segmentations!"; + InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, gui_title); + + //----------------------------------------------- + // (When treating this as RGBA, last bits should ensure opaque) + // This assumes 4096 (2^12) > labels + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + /// RGBA channels: Move labels to RGB + masks[x + y*width] <<= 4; + masks[x + y*width] |= 0x000F; + } + } + //----------------------------------------------- + + //----------------------------------------------- + //-RAYLIB-IMAGE-STRUCTURING---------------------- + //----------------------------------------------- + Image RaylibImage; + RaylibImage.width = width; + RaylibImage.height = height; + RaylibImage.mipmaps = 1; + // Use Contiguous Labels + RaylibImage.data = masks; + RaylibImage.format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4; + //----------------------------------------------- + + // Image to a Texture + Texture2D RaylibTexture = LoadTextureFromImage(RaylibImage); + + // Scale the image to the viewport + /// Source Rectangle: Original Size + Rectangle sourceRec = { 0.0f, 0.0f, (float)width, (float)height }; + /// Destination Rectangle: Transformed Size + Rectangle destRec = { 0.0f, 0.0f, (float)SCREEN_WIDTH, (float)(SCREEN_HEIGHT-OFFSET) }; + /// Location to begin drawing + Vector2 origin = { (float)0, (float)-OFFSET }; + + // Raylib boilerplate + SetTargetFPS(60); + Camera2D camera = { 0 }; + camera.zoom = 1.0f; + + // GUI Loop + while (!WindowShouldClose()) { + //----------------------------------------------- + //-DRAWING--------------------------------------- + //----------------------------------------------- + BeginDrawing(); + ClearBackground(RAYWHITE); + BeginMode2D(camera); + EndMode2D(); + DrawText("Image Manip", 0, 0, OFFSET, DARKGRAY); + DrawTexturePro(RaylibTexture, sourceRec, destRec, origin, (float)0, + RAYWHITE); + /* + uint32_t x = 0x49, y = 0x4A; + uint32_t dx = 0x69 - x, dy = 0x6E - y; + x = (SCREEN_WIDTH*x)/width; + y = SCREEN_HEIGHT-((SCREEN_HEIGHT-OFFSET)*y)/height; + dx = (SCREEN_WIDTH*dx)/width; + dy = SCREEN_HEIGHT-((SCREEN_HEIGHT-OFFSET)*dy)/height; + DrawRectangleGradientH(x, y, dx, dy, BLUE, PURPLE); + */ + EndDrawing(); + //----------------------------------------------- + } + + //----------------------------------------------- + //-SAVE-MASK-AS-BINARY-AND-PNG------------------- + //----------------------------------------------- + if (masks != NULL) { + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + /// Restore labels from RGBA + masks[x + y*width] &= 0xFFF0; + masks[x + y*width] >>= 4; + } + } + struct bitmap_t* bitmap = uint16_to_bitmap(masks, width, height); + if (bitmap != NULL) { + save_png(bitmap, png_file); + free(bitmap); + } + write_array(bin_file, masks, width*height*sizeof(uint16_t)); + free(masks); + } + CloseWindow(); +#else + //----------------------------------------------- + //-SAVE-MASK-AS-BINARY-AND-PNG------------------- + //----------------------------------------------- + if (masks != NULL) { + struct bitmap_t* bitmap = uint16_to_bitmap(masks, width, height); + if (bitmap != NULL) { + save_png(bitmap, png_file); + free(bitmap); + } + write_array(bin_file, masks, width*height*sizeof(uint16_t)); + free(masks); + } +#endif + TIME(ts_g_end); + if (!silent) { + printf("Finished in %f ms\n", 1000*diff_time(&ts_g_end, &ts_g_start)); + } + return 0; +} |