implemented distance maps
This commit is contained in:
parent
78e17be088
commit
092e993212
|
@ -5,4 +5,5 @@ set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
add_executable(Juniorcamp main.c)
|
add_executable(Juniorcamp main.c)
|
||||||
|
|
||||||
target_link_libraries(Juniorcamp imago)
|
target_link_libraries(Juniorcamp imago m)
|
||||||
|
target_link_directories(Juniorcamp PRIVATE /usr/local/lib/)
|
138
main.c
138
main.c
|
@ -1,26 +1,150 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <memory.h>
|
||||||
#include <imago2.h>
|
#include <imago2.h>
|
||||||
|
|
||||||
|
#define DEBUG_BUILD 0
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint8_t* buffer;
|
uint32_t* buffer;
|
||||||
|
uint32_t* dist_buffer;
|
||||||
} image_T;
|
} image_T;
|
||||||
|
|
||||||
|
uint32_t pixel_distance(uint32_t pixel_a, uint32_t pixel_b) {
|
||||||
|
uint8_t r_a = (pixel_a) & 0xFF;
|
||||||
|
uint8_t g_a = (pixel_a >> 8) & 0xFF;
|
||||||
|
uint8_t b_a = (pixel_a >> 16) & 0xFF;
|
||||||
|
|
||||||
|
uint8_t r_b = (pixel_b) & 0xFF;
|
||||||
|
uint8_t g_b = (pixel_b >> 8) & 0xFF;
|
||||||
|
uint8_t b_b = (pixel_b >> 16) & 0xFF;
|
||||||
|
|
||||||
|
uint32_t dist = (uint32_t)sqrt(pow(r_a - r_b, 2) +
|
||||||
|
pow(g_a - g_b, 2) +
|
||||||
|
pow(b_a - b_b, 2));
|
||||||
|
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
printf(" %x %x %x --> %x %x %x = %d\n", r_a, g_a, b_a, r_b, g_b, b_b, dist);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_T* image_load(const char* filename) {
|
||||||
|
printf("loading '%s'...\n", filename);
|
||||||
|
|
||||||
|
image_T* image = malloc(sizeof(image_T));
|
||||||
|
image->buffer = img_load_pixels(filename, (int*)&image->width, (int*)&image->height, IMG_FMT_RGBA32);
|
||||||
|
image->dist_buffer = calloc(image->width * image->height, sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void image_destruct(image_T* image) {
|
||||||
|
printf("destructing resources\n");
|
||||||
|
|
||||||
|
img_free_pixels(image->buffer);
|
||||||
|
free(image->dist_buffer);
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image_calculate_dist_buffer(image_T* image) {
|
||||||
|
memset(image->dist_buffer, 0, image->height * image->width * sizeof(uint32_t));
|
||||||
|
|
||||||
|
uint32_t* last_row = image->buffer;
|
||||||
|
uint32_t* pixel_row = &last_row[image->height+1];
|
||||||
|
uint32_t* dist_last_row = image->dist_buffer;
|
||||||
|
uint32_t* dist_pixel_row = &dist_last_row[image->height+1];
|
||||||
|
|
||||||
|
for (int y = 1; y < image->height; y++) {
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
printf(" Y\n");
|
||||||
|
#endif
|
||||||
|
for (int x = 0; x < image->width; x++) {
|
||||||
|
uint32_t pixel = pixel_row[x];
|
||||||
|
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
printf(" X\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t shortest_dist = -1;
|
||||||
|
for (int i = (x > 0 ? -1 : 0); i < (x < image->width-1 ? 2 : 1); i++) {
|
||||||
|
uint32_t dist = pixel_distance(pixel, last_row[x + i]) + dist_last_row[x + i];
|
||||||
|
|
||||||
|
if (shortest_dist == -1 || shortest_dist > dist) {
|
||||||
|
shortest_dist = (int32_t)dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
printf(" 0x%x - %d\n", dist, x+i);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
printf(" 0x%x\n", shortest_dist);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dist_pixel_row[x] = shortest_dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_row = pixel_row;
|
||||||
|
pixel_row = &last_row[image->height+1];
|
||||||
|
dist_last_row = dist_pixel_row;
|
||||||
|
dist_pixel_row = &dist_last_row[image->height+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void image_dump(image_T* image) {
|
||||||
|
printf("Pixels:\n");
|
||||||
|
for (int y = 0; y < image->height; y++) {
|
||||||
|
uint32_t* pixel_row = &image->buffer[y * (image->height+1)];
|
||||||
|
|
||||||
|
printf(" ");
|
||||||
|
for (int x = 0; x < image->width; x++) {
|
||||||
|
printf("%x ", pixel_row[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Distances:\n");
|
||||||
|
for (int y = 0; y < image->height; y++) {
|
||||||
|
uint32_t* dist_row = &image->dist_buffer[y * (image->height+1)];
|
||||||
|
|
||||||
|
printf(" ");
|
||||||
|
for (int x = 0; x < image->width; x++) {
|
||||||
|
printf("%x ", dist_row[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t test_array[12] = {
|
||||||
|
0x00000001, 0x00000003, 0x00000005, 0x00000001,
|
||||||
|
0x00000001, 0x00000007, 0x00000001, 0x00000002,
|
||||||
|
0x0000000A, 0x00000003, 0x00000002, 0x00000005
|
||||||
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
printf("Line Cutter - Juniorcamp Informatik\n");
|
printf("Line Cutter - Juniorcamp Informatik\n");
|
||||||
|
|
||||||
const char* filename = "../paris.png";
|
// image_T* image = image_load("../paris.png");
|
||||||
|
|
||||||
printf("loading '%s'...\n", filename);
|
image_T* image = malloc(sizeof(image_T));
|
||||||
image_T image;
|
image->height = 3;
|
||||||
image.buffer = img_load_pixels(filename, (int*)&image.width, (int*)&image.height, IMG_FMT_RGBA32);
|
image->width = 4;
|
||||||
|
image->buffer = test_array;
|
||||||
|
image->dist_buffer = calloc(image->width * image->height, sizeof(uint32_t));
|
||||||
|
|
||||||
|
image_calculate_dist_buffer(image);
|
||||||
|
image_dump(image);
|
||||||
|
|
||||||
|
|
||||||
printf("destructing resources\n");
|
// image_destruct(image);
|
||||||
img_free_pixels(image.buffer);
|
free(image->dist_buffer);
|
||||||
|
free(image);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue