surfaces-unies/src/common.c
2018-11-06 16:08:20 +01:00

71 lines
2.2 KiB
C

#include "common.h"
bool sameColor(Pixel_t t_pixel, Zone_t t_zone) {
return t_pixel->r == t_zone->r && t_pixel->g == t_zone->g &&
t_pixel->b == t_zone->b;
}
/* Adds a pixel to a zone, since the pixel isn't in a zone, then it isn't
part of a segment either, hence we can confidently add pixels next to the
original as parts of the segment and add the segment itself to the zone */
void addPixelToSelectedZone(Image_t t_img, int t_idx, Zone_t t_zone) {
Pixel_t current_pixel;
int xd, xg;
current_pixel = darrayGet(t_img->pixels, t_idx);
if (current_pixel->visited || t_idx >= (int)darraySize(t_img->pixels) ||
t_idx < 0 || !sameColor(current_pixel, t_zone)) {
return;
}
(*current_pixel).visited = true;
for(xd = t_idx; xd % (int)t_img->x != 0; ++xd) { /* fetch right limit of segment */
current_pixel = darrayGet(t_img->pixels, xd);
if(!sameColor(current_pixel, t_zone)) {
break;
}
(*current_pixel).visited = true;
}
for(xg = t_idx; xg % t_img->x >= 0; --xg) { /* fetch right limit of segment */
current_pixel = darrayGet(t_img->pixels, xd);
if(!sameColor(current_pixel, t_zone)) {
break;
}
(*current_pixel).visited = true;
}
/* Add segment to its zone */
darrayPushBack(t_zone->segments, newSegment(t_idx / t_img->x, xd, xg));
for(; xg <= xd; ++xg) { /* process every pixel up and down the segment */
addPixelToSelectedZone(t_img, t_idx + t_img->x, t_zone);
}
}
/* Selects the zone related to the pixel, skip tests if pixel has
already been visited */
void chooseZoneForPixel(Image_t t_img, int t_idx, darray_t zones) {
Zone_t current_zone;
Pixel_t pixel;
size_t i;
pixel = darrayGet(t_img->pixels, t_idx);
if (pixel->visited)
return;
for (i = 0; i < darraySize(zones); ++i) {
current_zone = darrayGet(zones, i);
if (sameColor(pixel, current_zone)) {
addPixelToSelectedZone(t_img, t_idx, current_zone);
break;
}
}
}
/* converts an image to zones */
darray_t imgToZones(Image_t t_img) {
darray_t zones;
const size_t nb_pixels = darraySize(t_img->pixels);
size_t i;
zones = darrayNew(sizeof(Zone));
for (i = 0; i < nb_pixels; ++i) {
chooseZoneForPixel(t_img, i, zones);
}
return zones;
}