#include #include 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); }