Create utils.cpp

This commit is contained in:
augustin64 2025-04-03 16:25:27 +02:00
parent 7b07f66bfb
commit 095b14d3a9
4 changed files with 46 additions and 32 deletions

View File

@ -9,6 +9,7 @@ project (seam-carving)
# Add an executable with the above sources
add_executable(seam-carving src/seam-carving.cpp)
add_library(utils src/utils.cpp)
# Set the directories that should be included in the build command for this target
# when running g++ these will be included as -I/directory/path/
@ -16,3 +17,4 @@ target_include_directories(seam-carving
PRIVATE
${PROJECT_SOURCE_DIR}/deps
)
target_link_libraries(seam-carving utils)

View File

@ -11,6 +11,7 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <SimpleProgressBar.hpp>
#include <stb_image_write.h>
#include "utils.hpp"
#define DEFAULT_SEAMS 1
@ -24,35 +25,6 @@ int max_step = 1;
// : dim_long, b : dim_large
#define im_index(a, b) (vertical ? (width * a + b) : (width * b + a))
bool nearly_equal(float a, float b) {
return std::nextafter(a, std::numeric_limits<float>::lowest()) <= b &&
std::nextafter(a, std::numeric_limits<float>::max()) >= b;
}
std::pair<int, float> operator+(std::pair<int, float>& p1, std::pair<int, float>& 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<int, float>& p1, std::pair<int, float>& p2) {
p1 = p1+p2;
}
namespace limits {
struct max_energy {
template<class T> operator T() {
return std::numeric_limits<T>::max();
}
operator std::pair<int, float>() {
return {3, std::numeric_limits<float>::max()};
}
};
}
void export_image(const char *filename, const void *data, int width, int height,
int nbChannels) {
@ -133,9 +105,9 @@ template <typename T> std::vector<int> optimal_seam(std::vector<T> energy, int w
for (auto k = lower_bound; k <= upper_bound;
k++) { // Compute energy based on predecessors
dyn_energy[dim_large * i + j] = std::min(
dyn_energy[dim_large * i + j], dyn_energy[dim_large * (i - 1) + k]
);
if (dyn_energy[dim_large*(i-1)+k] < dyn_energy[dim_large*i+j]) {
dyn_energy[dim_large*i+j] = dyn_energy[dim_large*(i-1)+k];
}
}
dyn_energy[dim_large * i + j] += energy[im_index(i, j)];
}

21
src/utils.cpp Normal file
View File

@ -0,0 +1,21 @@
#include <iostream>
#include <random>
#include <vector>
bool nearly_equal(float a, float b) {
return std::nextafter(a, std::numeric_limits<float>::lowest()) <= b &&
std::nextafter(a, std::numeric_limits<float>::max()) >= b;
}
std::pair<int, float> operator+(std::pair<int, float>& p1, std::pair<int, float>& 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<int, float>& p1, std::pair<int, float>& p2) {
p1 = p1+p2;
}

19
src/utils.hpp Normal file
View File

@ -0,0 +1,19 @@
#include <random>
bool nearly_equal(float a, float b);
std::pair<int, float> operator+(std::pair<int, float>& p1, std::pair<int, float>& p2);
void operator+=(std::pair<int, float>& p1, std::pair<int, float>& p2);
namespace limits {
struct max_energy {
template<class T> operator T() {
return std::numeric_limits<T>::max();
}
operator std::pair<int, float>() {
return {3, std::numeric_limits<float>::max()};
}
};
}