#include #include #include #include #define STB_IMAGE_IMPLEMENTATION #include #define STB_IMAGE_WRITE_IMPLEMENTATION #include #include "utils.hpp" bool nearly_equal(float a, float b) { return std::nextafter(a, std::numeric_limits::lowest()) <= b && std::nextafter(a, std::numeric_limits::max()) >= b; } bool does_seam_remove_mask(std::vector> energy, int width, int height, int nbChannels, std::vector opt_seam, bool vertical) { int dim_large = vertical ? width : height; int dim_long = vertical ? height : width; for (int i=0; i < dim_long; i++) { if (energy[im_index(i, opt_seam[i])].first == 0) return true; } return false; } std::vector> mask_energy(std::vector energy, int width, int height, unsigned char* mask) { std::vector> output(width*height); for (auto i=0; i < width*height; i++) { output[i] = {mask[i], energy[i]}; } return output; } std::pair operator+(std::pair& p1, std::pair& p2) { return { // If one of the two pixels is "protected" (ie 2), we want to prevent this line removing // Else, we want to keep the information of "is there a pixel to remove in this seam" (ie 0) (p1.first==2) || (p2.first==2) ? 2 : std::min(p1.first, p2.first), p1.second+p2.second }; } void operator+=(std::pair& p1, std::pair& p2) { p1 = p1+p2; } bool operator==(std::pair& p1, std::pair& p2) { return (p1.first==p2.first && p1.second == p2.second); } std::string str_of_e(std::pair energy) { std::stringstream ss; ss << "(" << energy.first << ", " << energy.second << ")"; return ss.str(); } std::string str_of_e(float energy) { std::stringstream ss; ss << "(" << energy << ")"; return ss.str(); }