diff --git a/src/blue_noise.cpp b/src/blue_noise.cpp index 1f0aea9..bbf25b5 100644 --- a/src/blue_noise.cpp +++ b/src/blue_noise.cpp @@ -114,7 +114,7 @@ std::vector dither::internal::blue_noise_impl(int width, int height, int t fprintf(random_noise_image, "P1\n%d %d\n", width, height); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - fprintf(random_noise_image, "%d ", pbp[internal::twoToOne(x, y, width)] ? 1 : 0); + fprintf(random_noise_image, "%d ", pbp[utility::twoToOne(x, y, width)] ? 1 : 0); } fputc('\n', random_noise_image); } @@ -196,7 +196,7 @@ std::vector dither::internal::blue_noise_impl(int width, int height, int t } } - if(internal::dist(max_one, second_min, width) < 1.5f) { + if(utility::dist(max_one, second_min, width) < 1.5f) { pbp[max_one] = true; break; } else { @@ -209,7 +209,7 @@ std::vector dither::internal::blue_noise_impl(int width, int height, int t fprintf(blue_noise_image, "P1\n%d %d\n", width, height); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - fprintf(blue_noise_image, "%d ", pbp[internal::twoToOne(x, y, width)] ? 1 : 0); + fprintf(blue_noise_image, "%d ", pbp[utility::twoToOne(x, y, width)] ? 1 : 0); } fputc('\n', blue_noise_image); } @@ -226,7 +226,7 @@ std::vector dither::internal::blue_noise_impl(int width, int height, int t fprintf(blue_noise_image, "P1\n%d %d\n", width, height); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - fprintf(blue_noise_image, "%d ", pbp[internal::twoToOne(x, y, width)] ? 1 : 0); + fprintf(blue_noise_image, "%d ", pbp[utility::twoToOne(x, y, width)] ? 1 : 0); } fputc('\n', blue_noise_image); } @@ -455,7 +455,7 @@ std::vector dither::internal::blue_noise_cl_impl( fprintf(random_noise_image, "P1\n%d %d\n", width, height); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - fprintf(random_noise_image, "%d ", pbp[internal::twoToOne(x, y, width)] ? 1 : 0); + fprintf(random_noise_image, "%d ", pbp[utility::twoToOne(x, y, width)] ? 1 : 0); } fputc('\n', random_noise_image); } @@ -524,7 +524,7 @@ std::vector dither::internal::blue_noise_cl_impl( } } - if(internal::dist(max_one, second_min, width) < 1.5f) { + if(utility::dist(max_one, second_min, width) < 1.5f) { pbp[max_one] = true; break; } else { @@ -537,7 +537,7 @@ std::vector dither::internal::blue_noise_cl_impl( fprintf(blue_noise_image, "P1\n%d %d\n", width, height); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - fprintf(blue_noise_image, "%d ", pbp[internal::twoToOne(x, y, width)] ? 1 : 0); + fprintf(blue_noise_image, "%d ", pbp[utility::twoToOne(x, y, width)] ? 1 : 0); } fputc('\n', blue_noise_image); } @@ -553,7 +553,7 @@ std::vector dither::internal::blue_noise_cl_impl( fprintf(blue_noise_image, "P1\n%d %d\n", width, height); for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - fprintf(blue_noise_image, "%d ", pbp[internal::twoToOne(x, y, width)] ? 1 : 0); + fprintf(blue_noise_image, "%d ", pbp[utility::twoToOne(x, y, width)] ? 1 : 0); } fputc('\n', blue_noise_image); } diff --git a/src/blue_noise.hpp b/src/blue_noise.hpp index 41ca383..f5ad4d5 100644 --- a/src/blue_noise.hpp +++ b/src/blue_noise.hpp @@ -2,8 +2,6 @@ #define BLUE_NOISE_HPP #include -#include -#include #include #include #include @@ -16,6 +14,8 @@ #include +#include "utility.hpp" + namespace dither { std::vector blue_noise(int width, int height, int threads = 1); @@ -52,14 +52,6 @@ namespace internal { return pbp; } - inline int twoToOne(int x, int y, int width) { - return x + y * width; - } - - inline std::pair oneToTwo(int i, int width) { - return {i % width, i / width}; - } - constexpr float mu_squared = 1.5f * 1.5f; inline float gaussian(float x, float y) { @@ -71,7 +63,7 @@ namespace internal { precomputed.reserve(size * size); for(int i = 0; i < size * size; ++i) { - auto xy = oneToTwo(i, size); + auto xy = utility::oneToTwo(i, size); precomputed.push_back(gaussian( (float)xy.first - size / 2.0f, (float)xy.second - size / 2.0f)); } @@ -93,7 +85,7 @@ namespace internal { int q_prime = (height + filter_size / 2 + y - q) % height; for(int p = 0; p < filter_size; ++p) { int p_prime = (width + filter_size / 2 + x - p) % width; - if(pbp[twoToOne(p_prime, q_prime, width)]) { + if(pbp[utility::twoToOne(p_prime, q_prime, width)]) { sum += gaussian((float)p - filter_size/2.0f, (float)q - filter_size/2.0f); } } @@ -113,8 +105,8 @@ namespace internal { int q_prime = (height + filter_size / 2 + y - q) % height; for(int p = 0; p < filter_size; ++p) { int p_prime = (width + filter_size / 2 + x - p) % width; - if(pbp[twoToOne(p_prime, q_prime, width)]) { - sum += precomputed[twoToOne(p, q, filter_size)]; + if(pbp[utility::twoToOne(p_prime, q_prime, width)]) { + sum += precomputed[utility::twoToOne(p, q, filter_size)]; } } } @@ -131,7 +123,7 @@ namespace internal { if(precomputed) { for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - filter_out[internal::twoToOne(x, y, width)] = + filter_out[utility::twoToOne(x, y, width)] = internal::filter_with_precomputed( pbp, x, y, width, height, filter_size, *precomputed); } @@ -139,7 +131,7 @@ namespace internal { } else { for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { - filter_out[internal::twoToOne(x, y, width)] = + filter_out[utility::twoToOne(x, y, width)] = internal::filter(pbp, x, y, width, height, filter_size); } } @@ -164,7 +156,7 @@ namespace internal { std::vector *fout, const std::vector *precomputed) { int x, y; - std::tie(x, y) = internal::oneToTwo(i, width); + std::tie(x, y) = utility::oneToTwo(i, width); (*fout)[i] = internal::filter_with_precomputed( *pbp, x, y, width, height, filter_size, *precomputed); std::unique_lock lock(*cvm); @@ -192,7 +184,7 @@ namespace internal { int height, int filter_size, std::vector *fout) { int x, y; - std::tie(x, y) = internal::oneToTwo(i, width); + std::tie(x, y) = utility::oneToTwo(i, width); (*fout)[i] = internal::filter( *pbp, x, y, width, height, filter_size); std::unique_lock lock(*cvm); @@ -242,7 +234,7 @@ namespace internal { int idx, int width, int height) { std::queue checking_indices; - auto xy = oneToTwo(idx, width); + auto xy = utility::oneToTwo(idx, width); int count = 0; int loops = 0; enum { D_DOWN = 0, D_LEFT = 1, D_UP = 2, D_RIGHT = 3 } dir = D_RIGHT; @@ -293,7 +285,7 @@ namespace internal { break; } } - next = twoToOne(xy.first, xy.second, width); + next = utility::twoToOne(xy.first, xy.second, width); if((get_one && pbp[next]) || (!get_one && !pbp[next])) { return next; } @@ -319,14 +311,6 @@ namespace internal { } fclose(filter_image); } - - inline float dist(int a, int b, int width) { - auto axy = oneToTwo(a, width); - auto bxy = oneToTwo(b, width); - float dx = axy.first - bxy.first; - float dy = axy.second - bxy.second; - return std::sqrt(dx * dx + dy * dy); - } } // namespace dither::internal } // namespace dither diff --git a/src/utility.hpp b/src/utility.hpp new file mode 100644 index 0000000..0a49a48 --- /dev/null +++ b/src/utility.hpp @@ -0,0 +1,25 @@ +#ifndef DITHERING_UTILITY_HPP +#define DITHERING_UTILITY_HPP + +#include +#include + +namespace utility { + inline int twoToOne(int x, int y, int width) { + return x + y * width; + } + + inline std::pair oneToTwo(int i, int width) { + return {i % width, i / width}; + } + + inline float dist(int a, int b, int width) { + auto axy = utility::oneToTwo(a, width); + auto bxy = utility::oneToTwo(b, width); + float dx = axy.first - bxy.first; + float dy = axy.second - bxy.second; + return std::sqrt(dx * dx + dy * dy); + } +} + +#endif