Split utility functions to utility.hpp
This commit is contained in:
parent
e24606ea2c
commit
6ca0db1e57
3 changed files with 45 additions and 36 deletions
|
@ -114,7 +114,7 @@ std::vector<bool> dither::internal::blue_noise_impl(int width, int height, int t
|
||||||
fprintf(random_noise_image, "P1\n%d %d\n", width, height);
|
fprintf(random_noise_image, "P1\n%d %d\n", width, height);
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
fputc('\n', random_noise_image);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ std::vector<bool> 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;
|
pbp[max_one] = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,7 +209,7 @@ std::vector<bool> dither::internal::blue_noise_impl(int width, int height, int t
|
||||||
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
fputc('\n', blue_noise_image);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ std::vector<bool> dither::internal::blue_noise_impl(int width, int height, int t
|
||||||
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
fputc('\n', blue_noise_image);
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ std::vector<bool> dither::internal::blue_noise_cl_impl(
|
||||||
fprintf(random_noise_image, "P1\n%d %d\n", width, height);
|
fprintf(random_noise_image, "P1\n%d %d\n", width, height);
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
fputc('\n', random_noise_image);
|
||||||
}
|
}
|
||||||
|
@ -524,7 +524,7 @@ std::vector<bool> 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;
|
pbp[max_one] = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -537,7 +537,7 @@ std::vector<bool> dither::internal::blue_noise_cl_impl(
|
||||||
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
fputc('\n', blue_noise_image);
|
||||||
}
|
}
|
||||||
|
@ -553,7 +553,7 @@ std::vector<bool> dither::internal::blue_noise_cl_impl(
|
||||||
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
fprintf(blue_noise_image, "P1\n%d %d\n", width, height);
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
fputc('\n', blue_noise_image);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
#define BLUE_NOISE_HPP
|
#define BLUE_NOISE_HPP
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
|
||||||
#include <cmath>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
@ -16,6 +14,8 @@
|
||||||
|
|
||||||
#include <CL/opencl.h>
|
#include <CL/opencl.h>
|
||||||
|
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
namespace dither {
|
namespace dither {
|
||||||
|
|
||||||
std::vector<bool> blue_noise(int width, int height, int threads = 1);
|
std::vector<bool> blue_noise(int width, int height, int threads = 1);
|
||||||
|
@ -52,14 +52,6 @@ namespace internal {
|
||||||
return pbp;
|
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;
|
constexpr float mu_squared = 1.5f * 1.5f;
|
||||||
|
|
||||||
inline float gaussian(float x, float y) {
|
inline float gaussian(float x, float y) {
|
||||||
|
@ -71,7 +63,7 @@ namespace internal {
|
||||||
precomputed.reserve(size * size);
|
precomputed.reserve(size * size);
|
||||||
|
|
||||||
for(int i = 0; i < size * size; ++i) {
|
for(int i = 0; i < size * size; ++i) {
|
||||||
auto xy = oneToTwo(i, size);
|
auto xy = utility::oneToTwo(i, size);
|
||||||
precomputed.push_back(gaussian(
|
precomputed.push_back(gaussian(
|
||||||
(float)xy.first - size / 2.0f, (float)xy.second - size / 2.0f));
|
(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;
|
int q_prime = (height + filter_size / 2 + y - q) % height;
|
||||||
for(int p = 0; p < filter_size; ++p) {
|
for(int p = 0; p < filter_size; ++p) {
|
||||||
int p_prime = (width + filter_size / 2 + x - p) % width;
|
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);
|
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;
|
int q_prime = (height + filter_size / 2 + y - q) % height;
|
||||||
for(int p = 0; p < filter_size; ++p) {
|
for(int p = 0; p < filter_size; ++p) {
|
||||||
int p_prime = (width + filter_size / 2 + x - p) % width;
|
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 += precomputed[twoToOne(p, q, filter_size)];
|
sum += precomputed[utility::twoToOne(p, q, filter_size)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +123,7 @@ namespace internal {
|
||||||
if(precomputed) {
|
if(precomputed) {
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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(
|
internal::filter_with_precomputed(
|
||||||
pbp, x, y, width, height, filter_size, *precomputed);
|
pbp, x, y, width, height, filter_size, *precomputed);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +131,7 @@ namespace internal {
|
||||||
} else {
|
} else {
|
||||||
for(int y = 0; y < height; ++y) {
|
for(int y = 0; y < height; ++y) {
|
||||||
for(int x = 0; x < width; ++x) {
|
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);
|
internal::filter(pbp, x, y, width, height, filter_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +156,7 @@ namespace internal {
|
||||||
std::vector<float> *fout,
|
std::vector<float> *fout,
|
||||||
const std::vector<float> *precomputed) {
|
const std::vector<float> *precomputed) {
|
||||||
int x, y;
|
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(
|
(*fout)[i] = internal::filter_with_precomputed(
|
||||||
*pbp, x, y, width, height, filter_size, *precomputed);
|
*pbp, x, y, width, height, filter_size, *precomputed);
|
||||||
std::unique_lock lock(*cvm);
|
std::unique_lock lock(*cvm);
|
||||||
|
@ -192,7 +184,7 @@ namespace internal {
|
||||||
int height, int filter_size,
|
int height, int filter_size,
|
||||||
std::vector<float> *fout) {
|
std::vector<float> *fout) {
|
||||||
int x, y;
|
int x, y;
|
||||||
std::tie(x, y) = internal::oneToTwo(i, width);
|
std::tie(x, y) = utility::oneToTwo(i, width);
|
||||||
(*fout)[i] = internal::filter(
|
(*fout)[i] = internal::filter(
|
||||||
*pbp, x, y, width, height, filter_size);
|
*pbp, x, y, width, height, filter_size);
|
||||||
std::unique_lock lock(*cvm);
|
std::unique_lock lock(*cvm);
|
||||||
|
@ -242,7 +234,7 @@ namespace internal {
|
||||||
int idx, int width, int height) {
|
int idx, int width, int height) {
|
||||||
std::queue<int> checking_indices;
|
std::queue<int> checking_indices;
|
||||||
|
|
||||||
auto xy = oneToTwo(idx, width);
|
auto xy = utility::oneToTwo(idx, width);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int loops = 0;
|
int loops = 0;
|
||||||
enum { D_DOWN = 0, D_LEFT = 1, D_UP = 2, D_RIGHT = 3 } dir = D_RIGHT;
|
enum { D_DOWN = 0, D_LEFT = 1, D_UP = 2, D_RIGHT = 3 } dir = D_RIGHT;
|
||||||
|
@ -293,7 +285,7 @@ namespace internal {
|
||||||
break;
|
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])) {
|
if((get_one && pbp[next]) || (!get_one && !pbp[next])) {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
@ -319,14 +311,6 @@ namespace internal {
|
||||||
}
|
}
|
||||||
fclose(filter_image);
|
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::internal
|
||||||
|
|
||||||
} // namespace dither
|
} // namespace dither
|
||||||
|
|
25
src/utility.hpp
Normal file
25
src/utility.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef DITHERING_UTILITY_HPP
|
||||||
|
#define DITHERING_UTILITY_HPP
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace utility {
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
Loading…
Reference in a new issue