Fix image::Bl write, use image::Bl as result for blue_noise

This commit is contained in:
Stephen Seo 2021-02-11 11:33:14 +09:00
parent 5155b847ca
commit 5826c3677c
6 changed files with 134 additions and 82 deletions

View file

@ -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

View file

@ -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 {};

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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;