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);
}
}
}
- 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 {
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);
}
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);
}
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);
}
}
}
- 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 {
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);
}
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);
}
#define BLUE_NOISE_HPP
#include <vector>
-#include <utility>
-#include <cmath>
#include <functional>
#include <unordered_set>
#include <condition_variable>
#include <CL/opencl.h>
+#include "utility.hpp"
+
namespace dither {
std::vector<bool> blue_noise(int width, int height, int threads = 1);
return pbp;
}
- inline int twoToOne(int x, int y, int width) {
- return x + y * width;
- }
-
- inline std::pair<int, int> 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) {
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));
}
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);
}
}
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)];
}
}
}
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);
}
} 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);
}
}
std::vector<float> *fout,
const std::vector<float> *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);
int height, int filter_size,
std::vector<float> *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);
int idx, int width, int height) {
std::queue<int> 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;
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;
}
}
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