#include "mosaic.hpp"
void Mosaics::add(Image* im, unsigned dim) {
assert(dim == im->buf.w && dim == im->buf.h);
const rgb_t im_med = im->med();
const rgb_t im_avg = im->avg();
const unsigned char im_avg_dist = im_avg.dist(im_med); // smoothness
const unsigned char im_med_dist = im->dist(im_med); // average distance
#if 0
for (std::vector<entry_t>::iterator it = entries.begin(); it != entries.end();) {
if (it->dim == dim && it->im_med == im_med) {
if (im_med_dist > it->im_med_dist || (im_med_dist == it->im_med_dist && im_avg_dist > it->im_avg_dist)) {
// there are already better choices
LOG("not adding %p", im);
delete im;
return;
} else if (im_med_dist < it->im_med_dist || (im_med_dist == it->im_med_dist && im_avg_dist < it->im_avg_dist)) {
// we would be a better choice
LOG("purging %p", it->im);
delete it->im;
it = entries.erase(it);
continue;
}
}
++it;
}
#endif
entries.push_back((entry_t){
dim,
im,
im_avg,
im_med,
im_avg_dist,
im_med_dist,
});
}
Mosaics::~Mosaics() {
for (std::vector<entry_t>::iterator it = entries.begin(); it != entries.end(); ++it) {
delete it->im;
}
}
bool Mosaics::add(const Image* im) {
bool rv = false;
Image* i = im->box(config.mosaic_dim);
if (i) {
add(i, config.mosaic_dim);
rv = true;
}
i = im->box(config.mosaic_dim_half);
if (i) {
add(i, config.mosaic_dim_half);
rv = true;
}
return rv;
}
const Image* Mosaics::find_best(unsigned dim, rgb_t c, unsigned char& dist) const {
Image* im = NULL;
unsigned char im_avg_dist = -1;
dist = -1;
for (std::vector<entry_t>::const_iterator it = entries.begin(); it != entries.end(); ++it) {
if (it->dim != dim) continue;
unsigned char d = it->im_med.dist(c);
if ((d < dist) || (d == dist && (it->im_avg_dist < im_avg_dist || (it->im_avg_dist == im_avg_dist && rand()%2)))) {
dist = d;
im_avg_dist = it->im_avg_dist;
im = it->im;
}
}
return im;
}
const Image* Mosaics::find_best(const Image* im, double& dist) const {
std::vector<entry_t>::const_iterator best = entries.end();
for (std::vector<entry_t>::const_iterator it = entries.begin(); it != entries.end(); ++it) {
if (it->dim != im->buf.w || it->dim != im->buf.h) continue;
double cand_dist = im->fdist(it->im);
if (best == entries.end() || cand_dist < dist || (cand_dist == dist && rand() % 2)) {
dist = cand_dist;
best = it;
}
}
assert(best != entries.end());
return best->im;
}