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