diff options
author | Christian C <cc@localhost> | 2025-03-05 21:57:20 -0800 |
---|---|---|
committer | Christian C <cc@localhost> | 2025-03-05 21:57:20 -0800 |
commit | 22db7ab4cb3b2928095bd9775fb015a5e28487f6 (patch) | |
tree | 24f1d1538809795b8b356810b6b3e6fc8dc627b4 | |
parent | 74ae06a582b7c567caf3c04e5bf5dfabf6671f31 (diff) |
Save to PNG
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | include/lib/png.h | 22 | ||||
-rw-r--r-- | include/lib/seg/util.h | 3 | ||||
-rw-r--r-- | src/lib/png.c | 64 | ||||
-rw-r--r-- | src/lib/seg/util.c | 30 | ||||
-rw-r--r-- | src/main.c | 7 |
6 files changed, 126 insertions, 2 deletions
@@ -1,4 +1,4 @@ -PKGS=libtiff-4 raylib +PKGS=libtiff-4 raylib libpng EXE=prog BUILD_DIR=build/ OBJ_DIR=$(BUILD_DIR)obj/ diff --git a/include/lib/png.h b/include/lib/png.h new file mode 100644 index 0000000..e7943c2 --- /dev/null +++ b/include/lib/png.h @@ -0,0 +1,22 @@ +#ifndef INC_LIB_PNG_H +#define INC_LIB_PNG_H + +#include <stdint.h> +#include <sys/types.h> + +struct pixel_t { + uint8_t red; + uint8_t green; + uint8_t blue; +}; + +struct bitmap_t { + struct pixel_t* image_buffer; + size_t width; + size_t height; +}; + +// Save bitmap to file +void save_png(struct bitmap_t* bitmap, char* fname); + +#endif diff --git a/include/lib/seg/util.h b/include/lib/seg/util.h index c3c0060..fcafff6 100644 --- a/include/lib/seg/util.h +++ b/include/lib/seg/util.h @@ -31,4 +31,7 @@ uint16_t* combine_masks(uint16_t *destination, uint16_t *extra_labels, uint32_t // starting_label_p will be incremented for each label found in the image uint16_t* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, uint16_t *starting_label_p); +// Convert mask to bitmap +struct bitmap_t* uint16_to_bitmap(uint16_t* buffer, uint32_t width, uint32_t height); + #endif diff --git a/src/lib/png.c b/src/lib/png.c new file mode 100644 index 0000000..d12a765 --- /dev/null +++ b/src/lib/png.c @@ -0,0 +1,64 @@ +#include <lib/png.h> + +#include <stdio.h> +#include <png.h> + +// Save bitmap to file +void save_png(struct bitmap_t* bitmap, char* fname) +{ + FILE *fp; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + uint8_t pixel_size = 3; + uint8_t pixel_depth = 8; + png_byte ** row_pointers = NULL; + size_t x, y; + fp = fopen(fname, "wb"); + if (fp == NULL) { + fprintf(stderr, "Error opening file\n"); + return; + } + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + fprintf(stderr, "Error creating write structure\n"); + fclose(fp); + return; + } + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + fprintf(stderr, "Error creating info structure\n"); + fclose(fp); + return; + } + if (setjmp(png_jmpbuf(png_ptr))) { + fprintf(stderr, "Error setting jmp\n"); + fclose(fp); + return; + } + png_set_IHDR(png_ptr, info_ptr, + bitmap->width, bitmap->height, + pixel_depth, + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + row_pointers = png_malloc(png_ptr, bitmap->height*sizeof(png_byte*)); + for (y = 0; y < bitmap->height; y++) { + png_byte *row = png_malloc(png_ptr, sizeof(uint8_t)*bitmap->width*pixel_size); + row_pointers[y] = row; + for (x = 0; x < bitmap->width; x++) { + *row++ = bitmap->image_buffer[x + y*bitmap->width].red; + *row++ = bitmap->image_buffer[x + y*bitmap->width].green; + *row++ = bitmap->image_buffer[x + y*bitmap->width].blue; + } + } + png_init_io(png_ptr, fp); + png_set_rows(png_ptr, info_ptr, row_pointers); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + for (y = 0; y < bitmap->height; y++) { + png_free(png_ptr, row_pointers[y]); + } + png_free(png_ptr, row_pointers); + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); +} + diff --git a/src/lib/seg/util.c b/src/lib/seg/util.c index 530c326..10b8fa8 100644 --- a/src/lib/seg/util.c +++ b/src/lib/seg/util.c @@ -1,5 +1,6 @@ #include <lib/seg/util.h> #include <lib/algo/flood_fill.h> +#include <lib/png.h> #include <tiffio.h> #include <assert.h> #include <stdio.h> @@ -260,3 +261,32 @@ uint16_t* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, TIFFClose(tif); return labels; } + +// Convert mask to bitmap +struct bitmap_t* uint16_to_bitmap(uint16_t* buffer, uint32_t width, uint32_t height) +{ + struct pixel_t* out_buffer = (struct pixel_t*)calloc(width*height, sizeof(struct pixel_t)); + if (out_buffer == NULL) { + return NULL; + } + struct bitmap_t* bitmap = (struct bitmap_t*)malloc(sizeof(struct bitmap_t)); + if (bitmap == NULL) { + free(out_buffer); + return NULL; + } + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + size_t coord = x + y*width; + uint8_t red = (buffer[coord] & 0xF00) >> 4*2; + uint8_t green = (buffer[coord] & 0x0F0) >> 4*1; + uint8_t blue = (buffer[coord] & 0x00F) >> 4*0; + out_buffer[coord].red = red | (red << 4); + out_buffer[coord].green = green | (green << 4); + out_buffer[coord].blue = blue | (blue << 4); + } + } + bitmap->image_buffer = out_buffer; + bitmap->width = (size_t)width; + bitmap->height = (size_t)height; + return bitmap; +} @@ -4,6 +4,7 @@ #include <raylib.h> #include <lib/lib.h> +#include <lib/png.h> #include <lib/bool.h> #include <lib/monad.h> #include <lib/dir.h> @@ -191,7 +192,6 @@ int main(int argc, char** argv) } TIME(ts_end); printf("Dilation took %f ms\n", 1000*diff_time(&ts_end, &ts_start)); - //----------------------------------------------- #ifdef VISUAL @@ -282,6 +282,11 @@ int main(int argc, char** argv) CloseWindow(); #else if (masks != NULL) { + struct bitmap_t* bitmap = uint16_to_bitmap(masks, width, height); + if (bitmap != NULL) { + save_png(bitmap, "../out.png"); + free(bitmap); + } write_array("../out.bin", masks, width*height*sizeof(uint16_t)); free(masks); } |