#include #include #include #include #include #include #include #include #include #include #include #include #define TAG 50839 #define OFFSET 16 #define ONE_ROW 1 char* full_path(char* dir, char* file) { char* fpath = NULL; size_t dir_len = strlen(dir); size_t file_len = strlen(file); fpath = (char*)calloc(dir_len+file_len+2,sizeof(char)); strcpy(fpath,dir); strcpy(fpath+dir_len+1,file); fpath[dir_len] = '/'; return fpath; } bool_t is_tif_ext(char* file_name) { size_t file_len = strlen(file_name); if ((file_name[file_len-3] == 't') && (file_name[file_len-2] == 'i') && (file_name[file_len-1] == 'f')) { return TRUE; } return FALSE; } uint16_t* combine_masks(uint16_t *destination, uint16_t *extra_labels, size_t width, size_t height) { if (destination == NULL) { destination = (uint16_t*)calloc(width*height, sizeof(uint16_t)); } for (size_t y = 0; y < height; y++) { for (size_t x = 0; x < width; x++) { size_t coord = x + y*width; if (destination[coord] == 0) { destination[coord] = extra_labels[coord]; } } } return destination; } uint16_t* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, uint16_t *starting_label_p) { //----------------------------------------------- //-TIFF-IMAGE-OPEN------------------------------- //----------------------------------------------- TIFF *tif = TIFFOpen(tif_file_name, "r"); if (!tif) { fprintf(stderr, "Failed to open TIFF file\n"); return NULL; } //----------------------------------------------- //----------------------------------------------- //-TIFF-FIND-DIMENSIONS-------------------------- //----------------------------------------------- size_t channels = 1; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, height); //----------------------------------------------- tmsize_t STRIP_LENGTH = TIFFStripSize(tif); tmsize_t STRIP_COUNT = TIFFNumberOfStrips(tif); if ((*width)*(*height)*3 == STRIP_LENGTH*STRIP_COUNT) { channels = 3; } else if ((*width)*(*height)*4 == STRIP_LENGTH*STRIP_COUNT) { channels = 4; } //----------------------------------------------- //----------------------------------------------- //-TIFF-LOAD-DATA-------------------------------- //----------------------------------------------- void* buffer = malloc(STRIP_LENGTH*sizeof(uint8_t)); if (buffer == NULL) { fprintf(stderr, "Memory allocation error\n"); TIFFClose(tif); return NULL; } uint8_t* image_data = calloc((*width)*(*height)*channels,sizeof(uint8_t)); if (image_data == NULL) { fprintf(stderr, "Memory allocation error\n"); free(buffer); TIFFClose(tif); return NULL; } for (size_t y = 0; y < STRIP_COUNT; y++) { tmsize_t strip_size = TIFFReadRawStrip(tif, y, buffer, STRIP_LENGTH); assert(strip_size == STRIP_LENGTH); for (size_t x = 0; x < STRIP_LENGTH; x++) { image_data[x + y*STRIP_LENGTH] = ((uint8_t*)buffer)[x]; } } free(buffer); //----------------------------------------------- //----------------------------------------------- //-FLOOD-FILL-SEGMENTATION----------------------- //-CONTIGUOUS-REGION-FINDING--------------------- //----------------------------------------------- uint16_t *labels = NULL; labels = (uint16_t*)calloc((*width)*(*height),sizeof(uint16_t)); if (labels == NULL) { fprintf(stderr, "Memory allocation error\n"); free(image_data); TIFFClose(tif); return NULL; } // Flood fill on each pixel // Increase label for each success for (size_t y = 0; y < *height; y++) { for (size_t x = 0; x < *width; x++) { size_t coord = x + y*(*width); if(flood(image_data, labels, *width, *height, channels, x, y, &(image_data[coord*channels]), *starting_label_p)) { *starting_label_p += 1; } } } free(image_data); TIFFClose(tif); return labels; } int main(int argc, char** argv) { //----------------------------------------------- //-LIST-FILES-IN-DIRECTORY----------------------- //----------------------------------------------- char** file_list = NULL; uint32_t width, height; uint16_t starting_label = 1; uint16_t *masks = NULL; if (argc > 1) { if (is_directory(argv[1])) { file_list = list_directory(argv[1]); if (file_list) { size_t index = 0; while (1) { char* fname = file_list[index]; if (fname == NULL) { break; } if (is_tif_ext(fname) == FALSE) { free(file_list[index++]); continue; } else { printf("Tiff found!\n"); } char* fpath = full_path(argv[1], fname); uint16_t *file_labels = tif_to_labels(fpath, &width, &height, &starting_label); masks = combine_masks(masks, file_labels, width, height); free(file_labels); printf("%s\n", fpath); free(fpath); printf("%s\n", fname); free(file_list[index++]); } free(file_list); } } } printf("%u %u\n", width, height); //free(masks); //----------------------------------------------- //----------------------------------------------- //-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++) { masks[x + y*width] |= 0xFF000000; } } //----------------------------------------------- //----------------------------------------------- //-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(); //----------------------------------------------- } if (masks != NULL) { free(masks); } CloseWindow(); return 0; }