]> git.seodisparate.com - blue_noise_generation/commitdiff
Some work on image objects
authorStephen Seo <seo.disparate@gmail.com>
Tue, 26 Jan 2021 13:25:34 +0000 (22:25 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Tue, 26 Jan 2021 13:25:34 +0000 (22:25 +0900)
src/image.cpp [new file with mode: 0644]
src/image.hpp [new file with mode: 0644]

diff --git a/src/image.cpp b/src/image.cpp
new file mode 100644 (file)
index 0000000..e763a65
--- /dev/null
@@ -0,0 +1,114 @@
+#include "image.hpp"
+
+#include <cstdio>
+#include <random>
+
+image::Bl::Bl(int width, int height) :
+data(width * height),
+width(width),
+height(height)
+{}
+
+image::Bl::Bl(const std::vector<uint8_t> &data, int width) :
+data(data),
+width(width),
+height(data.size() / width)
+{}
+
+image::Bl::Bl(std::vector<uint8_t> &&data, int width) :
+data(std::move(data)),
+width(width),
+height(data.size() / width)
+{}
+
+void image::Bl::randomize() {
+    std::default_random_engine re(std::random_device{}());
+    std::uniform_int_distribution<unsigned int> dist;
+
+    for(unsigned int i = 0; i < data.size(); ++i) {
+        data[i] = i < data.size() / 2 ? 255 : 0;
+    }
+
+    for(unsigned int i = 0; i < data.size() - 1; ++i) {
+        int ridx = dist(re, decltype(dist)::param_type{i+1, (unsigned int)data.size()-1});
+        uint8_t temp = data[i];
+        data[i] = data[ridx];
+        data[ridx] = temp;
+    }
+}
+
+int image::Bl::getSize() {
+    return data.size();
+}
+
+uint8_t* image::Bl::getData() {
+    return &data[0];
+}
+
+bool image::Bl::canWriteFile(file_type type) {
+    switch(type) {
+    case file_type::PBM:
+    case file_type::PGM:
+    case file_type::PPM:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool image::Bl::writeToFile(file_type type, bool canOverwrite, const char *filename) {
+    if(!canWriteFile(type)) {
+        return false;
+    }
+
+    FILE *file = fopen(filename, "r");
+    if(file && !canOverwrite) {
+        fclose(file);
+        return false;
+    }
+    fclose(file);
+
+    switch(type) {
+    case file_type::PBM:
+        file = fopen(filename, "w");
+        fprintf(file, "P1\n%d %d", width, height);
+        break;
+    case file_type::PGM:
+        file = fopen(filename, "wb");
+        fprintf(file, "P5\n%d %d\n255", width, height);
+        break;
+    case file_type::PPM:
+        file = fopen(filename, "wb");
+        fprintf(file, "P6\n%d %d\n255", width, height);
+        break;
+    default:
+        fclose(file);
+        return false;
+    }
+    for(unsigned int i = 0; i < data.size(); ++i) {
+        if(i % width == 0) {
+            fprintf(file, "\n");
+        }
+        switch(type) {
+        case file_type::PBM:
+            fprintf(file, "%d ", data[i] == 0 ? 0 : 1);
+            break;
+        case file_type::PGM:
+            fprintf(file, "%c ", data[i]);
+            break;
+        case file_type::PPM:
+            fprintf(file, "%c %c %c ", data[i], data[i], data[i]);
+            break;
+        default:
+            fclose(file);
+            return false;
+        }
+    }
+
+    fclose(file);
+    return true;
+}
+
+bool image::Bl::writeToFile(file_type type, bool canOverwrite, const std::string &filename) {
+    return writeToFile(type, canOverwrite, filename.c_str());
+}
diff --git a/src/image.hpp b/src/image.hpp
new file mode 100644 (file)
index 0000000..81fbbde
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef DITHERING_IMAGE_HPP
+#define DITHERING_IMAGE_HPP
+
+#include <cstdint>
+#include <vector>
+#include <string>
+
+namespace image {
+    enum class color_type {
+        Black,
+        Red,
+        Green,
+        Blue,
+        Alpha,
+    };
+
+    enum class file_type {
+        PBM,
+        PGM,
+        PPM,
+        // TODO PNG support
+    };
+
+    class base {
+    public:
+        base() = default;
+        virtual ~base() {}
+
+        base(const base &other) = default;
+        base(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 int getTypesCount() = 0;
+        virtual std::vector<color_type> getTypes() = 0;
+        virtual int getTypeStride(color_type type) = 0;
+
+        virtual bool canWriteFile(file_type type) = 0;
+        virtual bool writeToFile(file_type type, bool canOverwrite, const char *filename) = 0;
+        virtual bool writeToFile(file_type type, bool canOverwrite, const std::string &filename) = 0;
+    };
+
+    class Bl : public base {
+    public:
+        Bl(int width, int height);
+        Bl(const std::vector<uint8_t> &data, int width);
+        Bl(std::vector<uint8_t> &&data, int width);
+        virtual ~Bl() {}
+
+        Bl(const Bl &other) = default;
+        Bl(Bl &&other) = default;
+
+        Bl& operator=(const Bl &other) = default;
+        Bl& operator=(Bl &&other) = default;
+
+        virtual void randomize() override;
+
+        virtual int getSize() override;
+        virtual uint8_t* getData() override;
+
+        virtual int getTypesCount() override { return 1; }
+        virtual std::vector<color_type> getTypes() override { return { color_type::Black }; }
+        virtual int getTypeStride(color_type) override { return 0; }
+
+        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;
+    private:
+        std::vector<uint8_t> data;
+        int width;
+        int height;
+    };
+}
+
+#endif