Fix image::Bl write, use image::Bl as result for blue_noise
This commit is contained in:
parent
5155b847ca
commit
5826c3677c
6 changed files with 134 additions and 82 deletions
3
Makefile
3
Makefile
|
@ -9,7 +9,8 @@ endif
|
|||
|
||||
SOURCES= \
|
||||
src/main.cpp \
|
||||
src/blue_noise.cpp
|
||||
src/blue_noise.cpp \
|
||||
src/image.cpp
|
||||
OBJECTS=${subst .cpp,.o,${SOURCES}}
|
||||
|
||||
all: Dithering
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
# include <cstdio>
|
||||
#endif
|
||||
|
||||
std::vector<bool> dither::blue_noise(int width, int height, int threads) {
|
||||
image::Bl dither::blue_noise(int width, int height, int threads, bool use_opencl) {
|
||||
|
||||
bool use_opencl = false;
|
||||
bool using_opencl = false;
|
||||
|
||||
if(use_opencl) {
|
||||
// try to use OpenCL
|
||||
do {
|
||||
cl_device_id device;
|
||||
|
@ -86,13 +87,15 @@ std::vector<bool> dither::blue_noise(int width, int height, int threads) {
|
|||
clReleaseContext(context);
|
||||
|
||||
if(!result.empty()) {
|
||||
return result;
|
||||
return internal::toBl(result, width);
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
|
||||
if(!use_opencl) {
|
||||
std::cout << "OpenCL: Failed to setup/use, using regular impl..." << std::endl;
|
||||
return internal::blue_noise_impl(width, height, threads);
|
||||
if(!using_opencl) {
|
||||
std::cout << "OpenCL: Failed to setup/use or is not enabled, using regular impl..."
|
||||
<< std::endl;
|
||||
return internal::toBl(internal::blue_noise_impl(width, height, threads), width);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -11,14 +11,16 @@
|
|||
#include <cstdio>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <cassert>
|
||||
|
||||
#include <CL/opencl.h>
|
||||
|
||||
#include "utility.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
namespace dither {
|
||||
|
||||
std::vector<bool> blue_noise(int width, int height, int threads = 1);
|
||||
image::Bl blue_noise(int width, int height, int threads = 1, bool use_opencl = true);
|
||||
|
||||
namespace internal {
|
||||
std::vector<bool> blue_noise_impl(int width, int height, int threads = 1);
|
||||
|
@ -311,6 +313,18 @@ namespace internal {
|
|||
}
|
||||
fclose(filter_image);
|
||||
}
|
||||
|
||||
inline image::Bl toBl(const std::vector<bool>& pbp, int width) {
|
||||
image::Bl bwImage(width, pbp.size() / width);
|
||||
assert((unsigned long)bwImage.getSize() >= pbp.size()
|
||||
&& "New image::Bl size too small (pbp's size is not a multiple of width)");
|
||||
|
||||
for(unsigned int i = 0; i < pbp.size(); ++i) {
|
||||
bwImage.getData()[i] = pbp[i] ? 1 : 0;
|
||||
}
|
||||
|
||||
return bwImage;
|
||||
}
|
||||
} // namespace dither::internal
|
||||
|
||||
} // namespace dither
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
#include <cstdio>
|
||||
#include <random>
|
||||
|
||||
image::Bl::Bl() :
|
||||
data(),
|
||||
width(0),
|
||||
height(0)
|
||||
{}
|
||||
|
||||
image::Bl::Bl(int width, int height) :
|
||||
data(width * height),
|
||||
width(width),
|
||||
|
@ -22,6 +28,10 @@ height(data.size() / width)
|
|||
{}
|
||||
|
||||
void image::Bl::randomize() {
|
||||
if(!isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::default_random_engine re(std::random_device{}());
|
||||
std::uniform_int_distribution<unsigned int> dist;
|
||||
|
||||
|
@ -42,10 +52,23 @@ int image::Bl::getSize() {
|
|||
}
|
||||
|
||||
uint8_t* image::Bl::getData() {
|
||||
if(!isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &data[0];
|
||||
}
|
||||
|
||||
const uint8_t* image::Bl::getDataC() const {
|
||||
if(!isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &data[0];
|
||||
}
|
||||
|
||||
bool image::Bl::canWriteFile(file_type type) {
|
||||
if(!isValid()) {
|
||||
return false;
|
||||
}
|
||||
switch(type) {
|
||||
case file_type::PBM:
|
||||
case file_type::PGM:
|
||||
|
@ -57,7 +80,7 @@ bool image::Bl::canWriteFile(file_type type) {
|
|||
}
|
||||
|
||||
bool image::Bl::writeToFile(file_type type, bool canOverwrite, const char *filename) {
|
||||
if(!canWriteFile(type)) {
|
||||
if(!isValid() || !canWriteFile(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -66,7 +89,10 @@ bool image::Bl::writeToFile(file_type type, bool canOverwrite, const char *filen
|
|||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(file) {
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case file_type::PBM:
|
||||
|
@ -112,3 +138,7 @@ bool image::Bl::writeToFile(file_type type, bool canOverwrite, const char *filen
|
|||
bool image::Bl::writeToFile(file_type type, bool canOverwrite, const std::string &filename) {
|
||||
return writeToFile(type, canOverwrite, filename.c_str());
|
||||
}
|
||||
|
||||
bool image::Bl::isValid() const {
|
||||
return width > 0 && height > 0 && data.size() > 0;
|
||||
}
|
||||
|
|
|
@ -21,22 +21,22 @@ namespace image {
|
|||
// TODO PNG support
|
||||
};
|
||||
|
||||
class base {
|
||||
class Base {
|
||||
public:
|
||||
base() = default;
|
||||
virtual ~base() {}
|
||||
Base() = default;
|
||||
virtual ~Base() {}
|
||||
|
||||
base(const base &other) = default;
|
||||
base(base &&other) = default;
|
||||
Base(const Base &other) = default;
|
||||
Base(Base &&other) = default;
|
||||
|
||||
base& operator=(const base &other) = default;
|
||||
base& operator=(base &&other) = default;
|
||||
Base& operator=(const Base &other) = default;
|
||||
Base& operator=(Base &&other) = default;
|
||||
|
||||
virtual void randomize() = 0;
|
||||
|
||||
virtual int getSize() = 0;
|
||||
virtual uint8_t* getData() = 0;
|
||||
virtual const uint8_t* getDataC() { return getData(); }
|
||||
virtual const uint8_t* getDataC() const = 0;
|
||||
|
||||
virtual int getTypesCount() = 0;
|
||||
virtual std::vector<color_type> getTypes() = 0;
|
||||
|
@ -47,8 +47,9 @@ namespace image {
|
|||
virtual bool writeToFile(file_type type, bool canOverwrite, const std::string &filename) = 0;
|
||||
};
|
||||
|
||||
class Bl : public base {
|
||||
class Bl : public Base {
|
||||
public:
|
||||
Bl();
|
||||
Bl(int width, int height);
|
||||
Bl(const std::vector<uint8_t> &data, int width);
|
||||
Bl(std::vector<uint8_t> &&data, int width);
|
||||
|
@ -64,6 +65,7 @@ namespace image {
|
|||
|
||||
virtual int getSize() override;
|
||||
virtual uint8_t* getData() override;
|
||||
virtual const uint8_t* getDataC() const override;
|
||||
|
||||
virtual int getTypesCount() override { return 1; }
|
||||
virtual std::vector<color_type> getTypes() override { return { color_type::Black }; }
|
||||
|
@ -72,6 +74,7 @@ namespace image {
|
|||
virtual bool canWriteFile(file_type type) override;
|
||||
virtual bool writeToFile(file_type type, bool canOverwrite, const char *filename) override;
|
||||
virtual bool writeToFile(file_type type, bool canOverwrite, const std::string &filename) override;
|
||||
virtual bool isValid() const;
|
||||
private:
|
||||
std::vector<uint8_t> data;
|
||||
int width;
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
int main(int argc, char **argv) {
|
||||
//#ifndef NDEBUG
|
||||
std::cout << "Trying blue_noise..." << std::endl;
|
||||
dither::blue_noise(100, 100, 8);
|
||||
image::Bl bl = dither::blue_noise(100, 100, 8, true);
|
||||
bl.writeToFile(image::file_type::PBM, true, "blueNoiseOut.pbm");
|
||||
//#endif
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue