#include <stdlib.h>
#include <string.h>
unsigned area_size(unsigned char **, unsigned, unsigned, unsigned, unsigned);
unsigned char ** copy_area(unsigned char **, unsigned, unsigned);
void destroy_area(unsigned char **);
unsigned area_size (unsigned char ** area, unsigned width, unsigned height, unsigned x, unsigned y) {
if ((!area) || (x >= width) || (y >= height) || (!area[x][y])) return 0;
unsigned char ** copy = copy_area(area, width, height);
unsigned prevcount = 0, count = 1;
copy[x][y] = 2;
unsigned scan_area, scan_x, scan_y, neighbour_count;
for (scan_area = 1; prevcount != count; scan_area ++) {
prevcount = count;
for (scan_x = (x < scan_area) ? 0 : (x - scan_area); (scan_x < width) && (scan_x <= (x + scan_area)); scan_x ++)
for (scan_y = (y < scan_area) ? 0 : (y - scan_area); (scan_y < height) && (scan_y <= (y + scan_area)); scan_y ++) {
if (!copy[scan_x][scan_y]) continue;
if (
(scan_x && (copy[scan_x - 1][scan_y] == 2)) ||
(scan_y && (copy[scan_x][scan_y - 1] == 2)) ||
(copy[scan_x + 1][scan_y] == 2) ||
(copy[scan_x][scan_y + 1] == 2)
) {
if (copy[scan_x][scan_y] == 1) count ++;
copy[scan_x][scan_y] = 2;
}
}
}
destroy_area(copy);
return count;
}
unsigned char ** copy_area (unsigned char ** area, unsigned width, unsigned height) {
// this creates a copy of the area, and adds a surrounding border with 0s to the right and bottom to make coding easier
unsigned char ** result = calloc(sizeof(char *), width + 2);
unsigned x;
for (x = 0; x < width; x ++) {
memcpy(result[x] = malloc(height + 1), area[x], height);
result[x][height] = 0;
}
memset(result[width] = malloc(height + 1), 0, height + 1);
return result;
}
void destroy_area (unsigned char ** area) {
// this destroys the copy of the area created previously
unsigned x;
for (x = 0; area[x]; x ++) free(area[x]);
free(area);
}
Comments