diff options
54 files changed, 660 insertions, 329 deletions
@@ -1,7 +1,7 @@ -CXX=clang++ +CXX=g++ CXXFLAGS=-Iinclude -D_ATFILE_SOURCE -D_FORTIFY_SOURCE=0x2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_ISOC99_SOURCE -D_ISOC11_SOURCE -D_ISOC2X_SOURCE -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D__STDC_WANT_IEC_60559_BFP_EXT__ -D__STDC_WANT_IEC_60559_FUNCS_EXT__ -D__STDC_WANT_IEC_60559_TYPES_EXT__ -D__STDC_WANT_LIB_EXT2__=0x1 -ifneq ($(DEBUG),1) -CXXFLAGS += -DNDEBUG +ifneq ($(debug),1) +CXXFLAGS += -DNDEBUG -g endif CXXFLAGS += -std=c++20 -Wall -Wextra -Wpedantic CXXFLAGS += -march=native -mtune=native -O3 @@ -10,7 +10,22 @@ HDRS_CXX = \ include/benoit/archstr.hh \ include/benoit/arghandl.hh \ include/benoit/crtcfg.hh \ - include/benoit/dat.hh \ + include/benoit/d/arch.hh \ + include/benoit/d/cfg.hh \ + include/benoit/d/debug.hh \ + include/benoit/d/dobt.hh \ + include/benoit/d/imgfmt.hh \ + include/benoit/d/kernel.hh \ + include/benoit/d/logdoprint.hh \ + include/benoit/d/maxiter.hh \ + include/benoit/d/numthrds.hh \ + include/benoit/d/outimg.hh \ + include/benoit/d/pos.hh \ + include/benoit/d/printdolog.hh \ + include/benoit/d/resx.hh \ + include/benoit/d/resy.hh \ + include/benoit/d/thelog.hh \ + include/benoit/d/ver.hh \ include/benoit/exit.hh \ include/benoit/helpscrn.hh \ include/benoit/kernelstr.hh \ @@ -22,16 +37,29 @@ HDRS_CXX = \ include/benoit/plotmandelbrot.hh \ include/benoit/print.hh \ include/benoit/t/arch.hh \ - include/benoit/t/dat.hh \ include/benoit/t/imgfmt.hh \ include/benoit/t/kernel.hh \ include/benoit/t/pos.hh \ - include/benoit/t/thrddat.hh + include/benoit/t/rgba.hh \ + include/benoit/t/thrddat.hh \ + include/benoit/wrtimg.hh SRCS_CXX = \ src/benoit/archstr.cc \ src/benoit/arghandl.cc \ src/benoit/crtcfg.cc \ - src/benoit/dat.cc \ + src/benoit/d/cfg.cc \ + src/benoit/d/dobt.cc \ + src/benoit/d/imgfmt.cc \ + src/benoit/d/logdoprint.cc \ + src/benoit/d/maxiter.cc \ + src/benoit/d/numthrds.cc \ + src/benoit/d/outimg.cc \ + src/benoit/d/pos.cc \ + src/benoit/d/printdolog.cc \ + src/benoit/d/resx.cc \ + src/benoit/d/resy.cc \ + src/benoit/d/thelog.cc \ + src/benoit/d/ver.cc \ src/benoit/exit.cc \ src/benoit/helpscrn.cc \ src/benoit/kernelstr.cc \ @@ -43,6 +71,7 @@ SRCS_CXX = \ src/benoit/plotmandelbrot.cc \ src/benoit/print.cc \ src/benoit/t/pos/pos.cc \ + src/benoit/wrtimg.cc \ src/main.cc OBJS_CXX=$(SRCS_CXX:.cc=.o) OBJS=$(OBJS_CXX) @@ -1,2 +1,61 @@ # benoit ---- + +[*benoit*](https://mandelbrot.dk/delta/benoit) is a free and open-source Mandelbrot renderer written in C++ aimed at producing accurate Mandelbrot renders at arbitrary positions in the set as fast as possible. + +This speed is achieved by using all of the host's avaialable CPUs. + +This project is licensed under the GNU Affero General Public License version 3 as published by the Free Software Foundation. + +## Building + +The included Makefile is supposed to work for most platforms. + +In the event it doesn't, find a solution. + +## Dependencies + +This project depends on the following libraries: + +* Boost.Multiprecision (for multiprecision calculations) +* {FMT} (for string-formatting) +* GMP (a dependency of Boost.Multiprecision) +* libpng (for encoding PNG images) +* libwebp (for encoding WebP images) +* MPFR (a dependency of Boost.Multiprecision) +* pugixml (for XML parsing) + +The project is written for POSIX and therefore requires the POSIX libraries. + +Other than that, it also requires the target system to have the LLP64 data-model or greater. + +Targets with a pointer size of less than 64b are currently incompatible, but architectures like Aarch64, AMD64, IA-64 and PPC64 are expected to work, no-problem. + +## Questions + +### How can I donate? + +Thanks for considering it. What can I say? + +Sadly, I currently do not have any way for you to donate unless. + +But again thanks for wanting to do so. Here, have some glΓΈgg: π· + +### Why 64b-only? + +64b architectures use 32b to represent an `int`, while 32b architectures use 16b. + +32b systems are being deprecated by a lot of entities, and therefore it makes life easier to just expect a 64b data-mode. Why even bother, right? + +Well actually some embedded-systems use 32b processors, and to the user of those I say: *Suck my big duck!* + +### Why *blah blah blah*? + +Please ask a constructive question. + +### Why βbenoitβ? + +This project is named *benoit* in honour of Benoit Mandelbrot, the discoverer of the, you guessed it, Mandelbrot set. + +Benoit was a cool dude, but most people remember him only under the name *Mandelbrot*, if at all. + +I think Benoit is a cool name, and Mr. Mandelbrot was a cool dude, so why not make a cool programme? diff --git a/changelog.html b/changelog.html index 936cd43..39d3224 100644 --- a/changelog.html +++ b/changelog.html @@ -4,6 +4,18 @@ <meta charset="utf-8"> </head> <body> + <h1>6</h1> + <ul> + <li>Actually switch compiler from Clang++ to G++.</li> + <li>Add more command-line arguments.</li> + <li>Move all data variables into seperate files.</li> + <li>Update <i>README.md</i>.</li> + <li>Remove PPM as a supported format.</li> + <li>Change maximum resolution to 65536.</li> + <li>Change maximum number of threads to 65536.</li> + <li>Fix WebP encoding.</li> + <li>Create temporary renderer that renders a <i>test</i> image using multiple threads.</li> + </ul> <h1>5</h1> <ul> <li>Automatically detect number of threads.</li> diff --git a/include/benoit/d/arch.hh b/include/benoit/d/arch.hh new file mode 100644 index 0000000..71d8feb --- /dev/null +++ b/include/benoit/d/arch.hh @@ -0,0 +1,18 @@ +# pragma once +# include <benoit/t/arch.hh> +namespace benoit { + namespace d { + benoit::t::arch constexpr arch = +# if defined(__aarch64__) + benoit::t::arch::aarch64; +# elif (defined(_M_AMD64) || defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(x86_64__)) + benoit::t::arch::amd64; +# elif (defined(_IA64) defined(_M_IA64) || defined(__IA64__) || defined(__ia64__) || defined(__itanium__)) + benoit::t::arch::ia64; +# elif (defined(_ARCH_PPC64) || defined(__powerpc64__) || defined(__PPC64__) || defined(__ppc64__)) + benoit::t::arch::ppc64; +# else + benoit::t::arch::unknown; +# endif + } +} diff --git a/include/benoit/d/cfg.hh b/include/benoit/d/cfg.hh new file mode 100644 index 0000000..e2b2bf5 --- /dev/null +++ b/include/benoit/d/cfg.hh @@ -0,0 +1,7 @@ +# pragma once +# include <string> +namespace benoit { + namespace d { + std::string extern cfg; + } +} diff --git a/include/benoit/d/debug.hh b/include/benoit/d/debug.hh new file mode 100644 index 0000000..015eb17 --- /dev/null +++ b/include/benoit/d/debug.hh @@ -0,0 +1,11 @@ +# pragma once +namespace benoit { + namespace d { + bool constexpr debug = +# if defined(NDEBUG) + false; +# else + true; +# endif + } +} diff --git a/include/benoit/d/dobt.hh b/include/benoit/d/dobt.hh new file mode 100644 index 0000000..149eabb --- /dev/null +++ b/include/benoit/d/dobt.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + bool extern dobt; + } +} diff --git a/include/benoit/d/imgfmt.hh b/include/benoit/d/imgfmt.hh new file mode 100644 index 0000000..58bbc5f --- /dev/null +++ b/include/benoit/d/imgfmt.hh @@ -0,0 +1,7 @@ +# pragma once +# include <benoit/t/imgfmt.hh> +namespace benoit { + namespace d { + benoit::t::imgfmt extern imgfmt; + } +} diff --git a/include/benoit/d/kernel.hh b/include/benoit/d/kernel.hh new file mode 100644 index 0000000..b11d9a0 --- /dev/null +++ b/include/benoit/d/kernel.hh @@ -0,0 +1,26 @@ +# pragma once +# include <benoit/t/kernel.hh> +namespace benoit { + namespace d { + benoit::t::kernel constexpr kernel = +# if (defined(Macintosh) || defined(macintosh) || defined(__APPLE__) || defined(__MACH__)) + benoit::t::kernel::darwinos; +# elif defined(__DragonFly__) + benoit::t::kernel::dragonflybsd; +# elif defined(__FreeBSD__) + benoit::t::kernel::freebsd; +# elif (defined(__GNU__) || defined(__gnu_hurd__)) + benoit::t::kernel::hurd; +# elif defined(__linux__) + benoit::t::kernel::linux; +# elif defined(__minix) + benoit::t::kernel::minix; +# elif defined(__NetBSD__) + benoit::t::kernel::netbsd; +# elif defined(__OpenBSD__) + benoit::t::kernel::openbsd; +# else + benoit::t::kernel::unknown; +# endif + } +} diff --git a/include/benoit/d/logdoprint.hh b/include/benoit/d/logdoprint.hh new file mode 100644 index 0000000..801c134 --- /dev/null +++ b/include/benoit/d/logdoprint.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + bool extern logdoprint; + } +} diff --git a/include/benoit/d/maxiter.hh b/include/benoit/d/maxiter.hh new file mode 100644 index 0000000..00fc555 --- /dev/null +++ b/include/benoit/d/maxiter.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + unsigned long long extern maxiter; + } +} diff --git a/include/benoit/d/numthrds.hh b/include/benoit/d/numthrds.hh new file mode 100644 index 0000000..459f994 --- /dev/null +++ b/include/benoit/d/numthrds.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + unsigned extern numthrds; + } +} diff --git a/include/benoit/d/outimg.hh b/include/benoit/d/outimg.hh new file mode 100644 index 0000000..cfcd7df --- /dev/null +++ b/include/benoit/d/outimg.hh @@ -0,0 +1,7 @@ +# pragma once +# include <string> +namespace benoit { + namespace d { + std::string extern outimg; + } +} diff --git a/include/benoit/d/pos.hh b/include/benoit/d/pos.hh new file mode 100644 index 0000000..afaeb1d --- /dev/null +++ b/include/benoit/d/pos.hh @@ -0,0 +1,7 @@ +# pragma once +# include <benoit/t/pos.hh> +namespace benoit { + namespace d { + benoit::t::pos extern pos; + } +} diff --git a/include/benoit/d/printdolog.hh b/include/benoit/d/printdolog.hh new file mode 100644 index 0000000..85c58bc --- /dev/null +++ b/include/benoit/d/printdolog.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + bool extern printdolog; + } +} diff --git a/include/benoit/d/resx.hh b/include/benoit/d/resx.hh new file mode 100644 index 0000000..c90a790 --- /dev/null +++ b/include/benoit/d/resx.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + unsigned extern resx; + } +} diff --git a/include/benoit/d/resy.hh b/include/benoit/d/resy.hh new file mode 100644 index 0000000..7d502a8 --- /dev/null +++ b/include/benoit/d/resy.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + unsigned extern resy; + } +} diff --git a/include/benoit/d/thelog.hh b/include/benoit/d/thelog.hh new file mode 100644 index 0000000..edceb32 --- /dev/null +++ b/include/benoit/d/thelog.hh @@ -0,0 +1,8 @@ +# pragma once +# include <string> +# include <vector> +namespace benoit { + namespace d { + std::vector<std::string> extern thelog; + } +} diff --git a/include/benoit/d/ver.hh b/include/benoit/d/ver.hh new file mode 100644 index 0000000..79a8cf7 --- /dev/null +++ b/include/benoit/d/ver.hh @@ -0,0 +1,6 @@ +# pragma once +namespace benoit { + namespace d { + unsigned long long extern ver; + } +} diff --git a/include/benoit/dat.hh b/include/benoit/dat.hh deleted file mode 100644 index 7c4e7cf..0000000 --- a/include/benoit/dat.hh +++ /dev/null @@ -1,5 +0,0 @@ -# pragma once -# include <benoit/t/dat.hh> -namespace benoit { - benoit::t::dat extern dat; -} diff --git a/include/benoit/plotmandelbrot.hh b/include/benoit/plotmandelbrot.hh index 3d8b57a..f79b247 100644 --- a/include/benoit/plotmandelbrot.hh +++ b/include/benoit/plotmandelbrot.hh @@ -2,5 +2,5 @@ # include <cstdint> # include <vector> namespace benoit { - std::vector<std::uint8_t> plotmandelbrot(); + std::vector<std::uint8_t> * plotmandelbrot(); } diff --git a/include/benoit/t/dat.hh b/include/benoit/t/dat.hh deleted file mode 100644 index c43784b..0000000 --- a/include/benoit/t/dat.hh +++ /dev/null @@ -1,65 +0,0 @@ -# pragma once -# include <benoit/t/arch.hh> -# include <benoit/t/imgfmt.hh> -# include <benoit/t/kernel.hh> -# include <benoit/t/pos.hh> -# include <string> -# include <vector> -using namespace std::literals::string_literals; -namespace benoit { - namespace t { - class dat { - public: - benoit::t::arch constexpr static arch = -# if defined(__aarch64__) - benoit::t::arch::aarch64; -# elif (defined(_M_AMD64) || defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(x86_64__)) - benoit::t::arch::amd64; -# elif (defined(_IA64) defined(_M_IA64) || defined(__IA64__) || defined(__ia64__) || defined(__itanium__)) - benoit::t::arch::ia64; -# elif (defined(_ARCH_PPC64) || defined(__powerpc64__) || defined(__PPC64__) || defined(__ppc64__)) - benoit::t::arch::ppc64; -# else - benoit::t::arch::unknown; -# endif - benoit::t::imgfmt imgfmt = benoit::t::imgfmt::ppm; - benoit::t::kernel constexpr static kernel = -# if (defined(Macintosh) || defined(macintosh) || defined(__APPLE__) || defined(__MACH__)) - benoit::t::kernel::darwinos; -# elif defined(__DragonFly__) - benoit::t::kernel::dragonflybsd; -# elif defined(__FreeBSD__) - benoit::t::kernel::freebsd; -# elif (defined(__GNU__) || defined(__gnu_hurd__)) - benoit::t::kernel::hurd; -# elif defined(__linux__) - benoit::t::kernel::linux; -# elif defined(__minix) - benoit::t::kernel::minix; -# elif defined(__NetBSD__) - benoit::t::kernel::netbsd; -# elif defined(__OpenBSD__) - benoit::t::kernel::openbsd; -# else - benoit::t::kernel::unknown; -# endif - benoit::t::pos pos; - bool dobt = false; - bool printdolog = true; - bool debug = -# if defined(NDEBUG) - false; -# else - true; -# endif - long long ver = 0x5; - std::string cfg = "benoit.xml"s; - std::string outimg = "image"s; - std::vector<std::string> thelog = {}; - unsigned long long maxiter = 0x100ull; - unsigned numthrds = 0x1u; - unsigned resx = 0x100u; - unsigned resy = 0x100u; - }; - } -} diff --git a/include/benoit/t/imgfmt.hh b/include/benoit/t/imgfmt.hh index ffd6367..7efed27 100644 --- a/include/benoit/t/imgfmt.hh +++ b/include/benoit/t/imgfmt.hh @@ -3,7 +3,6 @@ namespace benoit { namespace t { enum class imgfmt { png, - ppm, webp, }; } diff --git a/include/benoit/t/rgba.hh b/include/benoit/t/rgba.hh new file mode 100644 index 0000000..e34112f --- /dev/null +++ b/include/benoit/t/rgba.hh @@ -0,0 +1,13 @@ +# pragma once +# include <cstdint> +namespace benoit { + namespace t { + class rgba { + public: + std::uint8_t a = 0xFF; + std::uint8_t b = 0x0; + std::uint8_t g = 0x0; + std::uint8_t r = 0x0; + }; + } +} diff --git a/include/benoit/t/thrddat.hh b/include/benoit/t/thrddat.hh index 75c8a05..1b691dc 100644 --- a/include/benoit/t/thrddat.hh +++ b/include/benoit/t/thrddat.hh @@ -1,15 +1,17 @@ # pragma once +# include <benoit/t/rgba.hh> # include <cstdint> # include <pthread.h> -# include <vector> namespace benoit { namespace t { class thrddat { public: - pthread_t * thrd = nullptr; - std::vector<std::uint8_t> * img = nullptr; - unsigned * rows = nullptr; - unsigned * id = nullptr; + pthread_t * thrd = nullptr; + std::uint8_t * thrdcol = nullptr; + benoit::t::rgba * img = nullptr; + unsigned * id = nullptr; + unsigned long long * imgbegin = nullptr; + unsigned long long * imgend = nullptr; }; } } diff --git a/include/benoit/wrtimg.hh b/include/benoit/wrtimg.hh new file mode 100644 index 0000000..ce4880b --- /dev/null +++ b/include/benoit/wrtimg.hh @@ -0,0 +1,6 @@ +# pragma once +# include <cstdint> +# include <vector> +namespace benoit { + void wrtimg(std::vector<std::uint8_t> * img); +} diff --git a/src/benoit/archstr.cc b/src/benoit/archstr.cc index 1c6d164..2feab4c 100644 --- a/src/benoit/archstr.cc +++ b/src/benoit/archstr.cc @@ -1,9 +1,13 @@ # include <benoit/archstr.hh> +# include <benoit/logfunc.hh> +# include <benoit/logfuncret.hh> # include <benoit/t/arch.hh> # include <string> # include <unordered_map> using namespace std::literals::string_literals; std::string benoit::archstr(benoit::t::arch arch) noexcept { + std::string const funcname = "benoit::archstr(benoit::t::arch)"s; + benoit::logfunc(funcname); std::unordered_map<benoit::t::arch,std::string> map = { { benoit::t::arch::aarch64, @@ -27,5 +31,6 @@ std::string benoit::archstr(benoit::t::arch arch) noexcept { } }; std::string str = map[arch]; + benoit::logfuncret(funcname); return str; } diff --git a/src/benoit/arghandl.cc b/src/benoit/arghandl.cc index 2b4026b..5cae6ad 100644 --- a/src/benoit/arghandl.cc +++ b/src/benoit/arghandl.cc @@ -1,6 +1,11 @@ # include <benoit/archstr.hh> # include <benoit/arghandl.hh> -# include <benoit/dat.hh> +# include <benoit/d/dobt.hh> +# include <benoit/d/imgfmt.hh> +# include <benoit/d/numthrds.hh> +# include <benoit/d/outimg.hh> +# include <benoit/d/resx.hh> +# include <benoit/d/resy.hh> # include <benoit/exit.hh> # include <benoit/helpscrn.hh> # include <benoit/kernelstr.hh> @@ -16,85 +21,99 @@ using namespace std::literals::string_literals; void benoit::arghandl(int const & argc,char const * * & argv) { std::string const funcname = "benoit::arghandl(int const &,char const * * &)"s; benoit::logfunc(funcname); - if(argc < 0x2) { - benoit::logfuncret(funcname); - return; - } - for(int pos = 0x1;(pos < argc);++pos) { - std::string arg = argv[pos]; - benoit::log(fmt::format("Found argument β{}β.",arg)); - std::string::size_type eqpos = arg.find("="s); - if(eqpos != std::string::npos) { - std::unordered_map<std::string,bool> strtobool = { - { - "false"s, - false, - }, - { - "true"s, - true, + if(argc > 0x1) { + benoit::log(fmt::format("{} argument(s) have been detected."s,(argc - 0x1))); + for(int pos = 0x1;(pos < argc);++pos) { + std::string arg = argv[pos]; + benoit::log(fmt::format("Found argument β{}β.",arg)); + std::string::size_type eqpos = arg.find("="s); + if(eqpos != std::string::npos) { + std::unordered_map<std::string,bool> strtobool = { + { + "false"s, + false, + }, + { + "true"s, + true, + } + }; + std::string invalvalforobj = "Unrecognised value β{}β for object β{}β."s; + std::string obj = arg.substr(0x0,eqpos); + benoit::log(funcname,fmt::format("Found object β{}β.",obj)); + std::string val = arg.substr(eqpos + 0x1); + benoit::log(funcname,fmt::format("Found value β{}β.",val)); + if(obj == "force-backtrace"s) { + if(!strtobool.contains(val)) { + benoit::print(fmt::format(invalvalforobj,val,obj)); + } + else { + benoit::d::dobt = strtobool[val]; + } } - }; - std::string invalvalforobj = "Unrecognised value β{}β for object β{}β."s; - std::string obj = arg.substr(0x0,eqpos); - benoit::log(funcname,fmt::format("Found object β{}β.",obj)); - std::string val = arg.substr(eqpos + 0x1); - benoit::log(funcname,fmt::format("Found value β{}β.",val)); - if(obj == "debug"s) { - if(!strtobool.contains(val)) { - benoit::print(fmt::format(invalvalforobj,val,obj)); + else if(obj == "format"s) { + if(val == "PNG"s) { + benoit::d::imgfmt = benoit::t::imgfmt::png; + } + else if(val == "WebP"s) { + benoit::d::imgfmt = benoit::t::imgfmt::webp; + } + else { + benoit::print(fmt::format(invalvalforobj,val,obj),true); + } } - else { - benoit::dat.debug = strtobool[val]; + else if(obj == "height"s) { + benoit::d::resy = std::stoi(val); + if(benoit::d::resy > 0x10000) { + benoit::print(fmt::format("Argument β{}β sets the height to {}, but the maximum width is 65536.",arg,benoit::d::resy),true); + benoit::d::resy = 0x10000; + } } - } - else if(obj == "format"s) { - if(val == "PNG"s) { - benoit::dat.imgfmt = benoit::t::imgfmt::png; + else if(obj == "output"s) { + benoit::d::outimg = val; } - else if(val == "PPM"s) { - benoit::dat.imgfmt = benoit::t::imgfmt::ppm; + else if(obj == "threads"s) { + benoit::d::numthrds = std::stoi(val); + if(benoit::d::numthrds > 0x10000) { + benoit::print(fmt::format("Argument β{}β sets the number of threads to {}, but the maximum number of threads is 65536."s,arg,benoit::d::numthrds),true); + benoit::d::numthrds = 0x10000; + } } - else if(val == "WebP"s) { - benoit::dat.imgfmt = benoit::t::imgfmt::webp; + else if(obj == "width"s) { + benoit::d::resx = std::stoi(val); + if(benoit::d::resx > 0x10000) { + benoit::print(fmt::format("Argument β{}β sets the width to {}, but the maximum width is 65536."s,arg,benoit::d::resx),true); + benoit::d::resx = 0x10000; + } } else { - benoit::print(fmt::format(invalvalforobj,val,obj),true); + benoit::print(fmt::format("Invalid object β{}β."s,obj),true); } } - else if(obj == "output"s) { - benoit::dat.outimg = val; - } - else if(obj == "threads"s) { - benoit::dat.numthrds = std::stoi(val); - } - else { - benoit::print(fmt::format("Invalid object β{}β."s,obj),true); - } - } - else { - if((arg == "help"s) || (arg == "--help"s)) { - benoit::helpscrn(); - } else { - benoit::print(fmt::format("Invalid argument β{}β."s,arg),true); + if((arg == "help"s) || (arg == "--help"s)) { + benoit::helpscrn(); + } + else { + benoit::print(fmt::format("Invalid argument β{}β."s,arg),true); + } } } } - switch(benoit::dat.imgfmt) { + else { + benoit::log("No arguments have been detected."s); + } + switch(benoit::d::imgfmt) { case benoit::t::imgfmt::png: - benoit::dat.outimg.append(".png"s); - break; - case benoit::t::imgfmt::ppm: - benoit::dat.outimg.append(".ppm"s); + benoit::d::outimg.append(".png"s); break; case benoit::t::imgfmt::webp: - if((benoit::dat.resx > 0x1000) || (benoit::dat.resy > 0x1000)) { - benoit::exit(EXIT_FAILURE,"WebP does not support a resolution of more than 4096"s); + if((benoit::d::resx > 0x3FFF) || (benoit::d::resy > 0x3FFF)) { + benoit::exit(EXIT_FAILURE,"WebP does not support a resolution of more than 16383."s); } - benoit::dat.outimg.append(".webp"s); + benoit::d::outimg.append(".webp"s); break; } - benoit::log(funcname,fmt::format("The output image will be \u201C{}\u201D."s,benoit::dat.outimg)); + benoit::log(funcname,fmt::format("The output image will be \u201C{}\u201D."s,benoit::d::outimg)); benoit::logfuncret(funcname); } diff --git a/src/benoit/crtcfg.cc b/src/benoit/crtcfg.cc index a09b0c8..202016c 100644 --- a/src/benoit/crtcfg.cc +++ b/src/benoit/crtcfg.cc @@ -1,8 +1,10 @@ # include <benoit/crtcfg.hh> # include <benoit/logfunc.hh> +# include <benoit/logfuncret.hh> # include <string> using namespace std::literals::string_literals; void benoit::crtcfg() { std::string const funcname = "benoit::crtcfg()"s; benoit::logfunc(funcname); + benoit::logfuncret(funcname); } diff --git a/src/benoit/d/cfg.cc b/src/benoit/d/cfg.cc new file mode 100644 index 0000000..7b9cf99 --- /dev/null +++ b/src/benoit/d/cfg.cc @@ -0,0 +1,4 @@ +# include <benoit/d/cfg.hh> +# include <string> +using namespace std::literals::string_literals; +std::string benoit::d::cfg = "benoit.xml"s; diff --git a/src/benoit/d/dobt.cc b/src/benoit/d/dobt.cc new file mode 100644 index 0000000..9643b6f --- /dev/null +++ b/src/benoit/d/dobt.cc @@ -0,0 +1,2 @@ +# include <benoit/d/dobt.hh> +bool benoit::d::dobt = false; diff --git a/src/benoit/d/imgfmt.cc b/src/benoit/d/imgfmt.cc new file mode 100644 index 0000000..412481a --- /dev/null +++ b/src/benoit/d/imgfmt.cc @@ -0,0 +1,3 @@ +# include <benoit/d/imgfmt.hh> +# include <benoit/t/imgfmt.hh> +benoit::t::imgfmt benoit::d::imgfmt = benoit::t::imgfmt::webp; diff --git a/src/benoit/d/logdoprint.cc b/src/benoit/d/logdoprint.cc new file mode 100644 index 0000000..5b68c6a --- /dev/null +++ b/src/benoit/d/logdoprint.cc @@ -0,0 +1,7 @@ +# include <benoit/d/logdoprint.hh> +bool benoit::d::logdoprint = +# if defined(NDEBUG) + false; +# else + true; +# endif diff --git a/src/benoit/d/maxiter.cc b/src/benoit/d/maxiter.cc new file mode 100644 index 0000000..477dd6f --- /dev/null +++ b/src/benoit/d/maxiter.cc @@ -0,0 +1,2 @@ +# include <benoit/d/maxiter.hh> +unsigned long long benoit::d::maxiter = 0x100ull; diff --git a/src/benoit/d/numthrds.cc b/src/benoit/d/numthrds.cc new file mode 100644 index 0000000..524ed82 --- /dev/null +++ b/src/benoit/d/numthrds.cc @@ -0,0 +1,2 @@ +# include <benoit/d/numthrds.hh> +unsigned benoit::d::numthrds = 0x1u; diff --git a/src/benoit/d/outimg.cc b/src/benoit/d/outimg.cc new file mode 100644 index 0000000..c6643ef --- /dev/null +++ b/src/benoit/d/outimg.cc @@ -0,0 +1,4 @@ +# include <benoit/d/outimg.hh> +# include <string> +using namespace std::literals::string_literals; +std::string benoit::d::outimg = "image"s; diff --git a/src/benoit/d/pos.cc b/src/benoit/d/pos.cc new file mode 100644 index 0000000..7930706 --- /dev/null +++ b/src/benoit/d/pos.cc @@ -0,0 +1,3 @@ +# include <benoit/d/pos.hh> +# include <benoit/t/pos.hh> +benoit::t::pos benoit::d::pos; diff --git a/src/benoit/d/printdolog.cc b/src/benoit/d/printdolog.cc new file mode 100644 index 0000000..8f4a8ae --- /dev/null +++ b/src/benoit/d/printdolog.cc @@ -0,0 +1,2 @@ +# include <benoit/d/printdolog.hh> +bool benoit::d::printdolog = true; diff --git a/src/benoit/d/resx.cc b/src/benoit/d/resx.cc new file mode 100644 index 0000000..9eeec0b --- /dev/null +++ b/src/benoit/d/resx.cc @@ -0,0 +1,2 @@ +# include <benoit/d/resx.hh> +unsigned benoit::d::resx = 0x100u; diff --git a/src/benoit/d/resy.cc b/src/benoit/d/resy.cc new file mode 100644 index 0000000..ddce771 --- /dev/null +++ b/src/benoit/d/resy.cc @@ -0,0 +1,2 @@ +# include <benoit/d/resy.hh> +unsigned benoit::d::resy = 0x100u; diff --git a/src/benoit/d/thelog.cc b/src/benoit/d/thelog.cc new file mode 100644 index 0000000..b925d3f --- /dev/null +++ b/src/benoit/d/thelog.cc @@ -0,0 +1,4 @@ +# include <benoit/d/thelog.hh> +# include <string> +# include <vector> +std::vector<std::string> benoit::d::thelog = {}; diff --git a/src/benoit/d/ver.cc b/src/benoit/d/ver.cc new file mode 100644 index 0000000..0e2860f --- /dev/null +++ b/src/benoit/d/ver.cc @@ -0,0 +1,2 @@ +# include <benoit/d/ver.hh> +unsigned long long benoit::d::ver = 0x6ull; diff --git a/src/benoit/dat.cc b/src/benoit/dat.cc deleted file mode 100644 index 5796fa1..0000000 --- a/src/benoit/dat.cc +++ /dev/null @@ -1,2 +0,0 @@ -# include <benoit/dat.hh> -benoit::t::dat benoit::dat; diff --git a/src/benoit/exit.cc b/src/benoit/exit.cc index 98d0619..8d1fb16 100644 --- a/src/benoit/exit.cc +++ b/src/benoit/exit.cc @@ -1,34 +1,43 @@ -# include <benoit/dat.hh> +# include <benoit/d/debug.hh> +# include <benoit/d/dobt.hh> +# include <benoit/d/printdolog.hh> +# include <benoit/d/thelog.hh> # include <benoit/exit.hh> # include <benoit/logfunc.hh> # include <benoit/print.hh> # include <cstdlib> # include <fmt/core.h> # include <string> -# include <time.h> +# include <unistd.h> using namespace std::literals::string_literals; [[noreturn]] void benoit::exit(int code,std::string msg) noexcept { std::string const funcname = "benoit::exit(int,std::string)"s; benoit::logfunc(funcname); - if(benoit::dat.debug) { - benoit::print(fmt::format("Exited with code {}: \"{}\"."s,code,msg),true); + if(code == EXIT_FAILURE) { + benoit::print(fmt::format("Exited with code {}: β{}β."s,code,msg),true); } - if((code == EXIT_FAILURE) || benoit::dat.dobt || benoit::dat.debug) { - benoit::dat.printdolog = false; + if(((code == EXIT_FAILURE) && !benoit::d::debug) || benoit::d::dobt) { + benoit::d::printdolog = false; benoit::print(""s); - benoit::print("+-------------"s); - benoit::print("| :Backtrace:"s); + benoit::print("+-------------------"s); + benoit::print("| :Backtrace Begin:"s); benoit::print("+-"s); benoit::print(""s); - for(auto entry : benoit::dat.thelog) { + for(auto entry : benoit::d::thelog) { { ::timespec sleepfor; sleepfor.tv_sec = 0x0; - sleepfor.tv_nsec = (0x3B9ACA00L / 0x3L); + sleepfor.tv_nsec = (0x3B9ACA00l / 0x6L); ::nanosleep(&sleepfor,nullptr); } benoit::print(entry); } + benoit::print(""s); + benoit::print("+-"s); + benoit::print("| :Backtrace End:"s); + benoit::print("+-----------------"s); + benoit::print(""s); + benoit::d::printdolog = true; } ::_exit(code); } diff --git a/src/benoit/helpscrn.cc b/src/benoit/helpscrn.cc index 1b9ef97..140f5ef 100644 --- a/src/benoit/helpscrn.cc +++ b/src/benoit/helpscrn.cc @@ -1,6 +1,8 @@ # include <benoit/archstr.hh> # include <benoit/helpscrn.hh> -# include <benoit/dat.hh> +# include <benoit/d/arch.hh> +# include <benoit/d/kernel.hh> +# include <benoit/d/ver.hh> # include <benoit/exit.hh> # include <benoit/kernelstr.hh> # include <benoit/logfunc.hh> @@ -112,24 +114,27 @@ using namespace std::literals::string_literals; datmod = fmt::format("{} AKA how the fuck did this get compiled?"s,datmod); } benoit::print(""s); - benoit::print(fmt::format("benoit {}",benoit::dat.ver)); + benoit::print(fmt::format("benoit {}",benoit::d::ver)); benoit::print("Copyright 2021 Gabriel Jensen"s); benoit::print(""s); benoit::print("Arguments:"s); - benoit::print("\u0009debug={false,true}:"s); - benoit::print("\u0009\u0009Sets whether or not to display debug information."s); - benoit::print("\u0009\u0009Some debugging information (for example assertions) will still require building a debug build."s); + benoit::print("\u0009force-backtrace={false,true}:"s); + benoit::print("\u0009\u0009Forces the backtrace of the at programme exit."s); + benoit::print("\u0009height={0..65536}:"s); + benoit::print("\u0009\u0009Sets the height for the rendered image."s); benoit::print("\u0009help, --help:"s); benoit::print("\u0009\u0009Displays this information screen."s); - benoit::print("\u0009threads={0..65535}:"s); + benoit::print("\u0009threads={0..65536}:"s); benoit::print("\u0009\u0009Sets the number of threads that will be used."s); + benoit::print("\u0009height={0..65536}:"s); + benoit::print("\u0009\u0009Sets the width for the rendered image."s); benoit::print(""s); benoit::print("Compilation Information:"s); - benoit::print(fmt::format("\u0009Architecture: {}"s,benoit::archstr(benoit::dat.arch))); + benoit::print(fmt::format("\u0009Architecture: {}"s,benoit::archstr(benoit::d::arch))); benoit::print(fmt::format("\u0009Compilation Date: {}"s,cmdate)); benoit::print(fmt::format("\u0009Compiler C++ Standard: {}"s,cppver)); benoit::print(fmt::format("\u0009Data Model: {}"s,datmod)); - benoit::print(fmt::format("\u0009System Kernel: {}"s,benoit::kernelstr(benoit::dat.kernel))); + benoit::print(fmt::format("\u0009System Kernel: {}"s,benoit::kernelstr(benoit::d::kernel))); benoit::print(""s); benoit::exit(EXIT_SUCCESS); } diff --git a/src/benoit/kernelstr.cc b/src/benoit/kernelstr.cc index 9239ac4..47616f8 100644 --- a/src/benoit/kernelstr.cc +++ b/src/benoit/kernelstr.cc @@ -1,9 +1,13 @@ # include <benoit/kernelstr.hh> +# include <benoit/logfunc.hh> +# include <benoit/logfuncret.hh> # include <benoit/t/kernel.hh> # include <string> # include <unordered_map> using namespace std::literals::string_literals; std::string benoit::kernelstr(benoit::t::kernel kernel) noexcept { + std::string const funcname = "benoit::kernelstr(benoit::t::kernel)"s; + benoit::logfunc(funcname); std::unordered_map<benoit::t::kernel,std::string> map = { { benoit::t::kernel::darwinos, @@ -43,5 +47,6 @@ std::string benoit::kernelstr(benoit::t::kernel kernel) noexcept { } }; std::string str = map[kernel]; + benoit::logfuncret(funcname); return str; } diff --git a/src/benoit/loadcfg.cc b/src/benoit/loadcfg.cc index b491201..937d5a8 100644 --- a/src/benoit/loadcfg.cc +++ b/src/benoit/loadcfg.cc @@ -1,11 +1,14 @@ # include <benoit/crtcfg.hh> -# include <benoit/dat.hh> +# include <benoit/d/cfg.hh> # include <benoit/loadcfg.hh> # include <iostream> # include <pugixml.hpp> +# include <string> # include <unistd.h> +using namespace std::literals::string_literals; void benoit::loadcfg() { - if(::access(benoit::dat.cfg.c_str(),R_OK) < 0x0) { + std::string const funcname = "benoit::loadcfg()"s; + if(::access(benoit::d::cfg.c_str(),R_OK) < 0x0) { benoit::crtcfg(); return; } diff --git a/src/benoit/log.cc b/src/benoit/log.cc index 92446ab..da7b683 100644 --- a/src/benoit/log.cc +++ b/src/benoit/log.cc @@ -1,16 +1,21 @@ -# include <benoit/dat.hh> +# include <benoit/d/logdoprint.hh> +# include <benoit/d/printdolog.hh> +# include <benoit/d/thelog.hh> # include <benoit/log.hh> # include <benoit/print.hh> # include <fmt/core.h> # include <string> +using namespace std::literals::string_literals; void benoit::log(std::string msg) { - if(benoit::dat.debug) { + std::string const funcname = "benoit::log(std::string)"s; + if(benoit::d::logdoprint) { + benoit::d::printdolog = false; benoit::print(msg,true); + benoit::d::printdolog = true; } - else { - benoit::dat.thelog.insert(benoit::dat.thelog.begin(),msg); - } + benoit::d::thelog.insert(benoit::d::thelog.begin(),msg); } void benoit::log(std::string const func,std::string msg) { + std::string const funcname = "benoit::log(std::string const,std::string)"s; msg = fmt::format("[{}] {}"s,func,msg); } diff --git a/src/benoit/logfunc.cc b/src/benoit/logfunc.cc index 54f4202..1a3c0bf 100644 --- a/src/benoit/logfunc.cc +++ b/src/benoit/logfunc.cc @@ -4,5 +4,6 @@ # include <string> using namespace std::literals::string_literals; void benoit::logfunc(std::string const func) { - benoit::log(fmt::format("Function call: {}."s,func)); + std::string const funcname = "benoit::logfunc(std::string const)"s; + benoit::log(fmt::format("\33[33mFunction call\33[0m: {}."s,func)); } diff --git a/src/benoit/logfuncret.cc b/src/benoit/logfuncret.cc index 6e52ede..5aae060 100644 --- a/src/benoit/logfuncret.cc +++ b/src/benoit/logfuncret.cc @@ -5,5 +5,5 @@ using namespace std::literals::string_literals; void benoit::logfuncret(std::string const func) { std::string const funcname = "benoit::logfuncret(std::string const)"s; - benoit::log(fmt::format("Function return: {}."s,func)); + benoit::log(fmt::format("\33[35mFunction return\33[0m: {}."s,func)); } diff --git a/src/benoit/main.cc b/src/benoit/main.cc index 2717955..267f7f1 100644 --- a/src/benoit/main.cc +++ b/src/benoit/main.cc @@ -2,7 +2,7 @@ static_assert(((sizeof(short) >= 0x2) && (sizeof(int) >= 0x4) && (sizeof(long) > # include <benoit/arghandl.hh> # include <benoit/log.hh> # include <benoit/logfunc.hh> -# include <benoit/dat.hh> +# include <benoit/d/numthrds.hh> # include <benoit/exit.hh> # include <benoit/loadcfg.hh> # include <benoit/log.hh> @@ -11,135 +11,21 @@ static_assert(((sizeof(short) >= 0x2) && (sizeof(int) >= 0x4) && (sizeof(long) > # include <benoit/main.hh> # include <benoit/plotmandelbrot.hh> # include <benoit/print.hh> -# include <cstddef> +# include <benoit/wrtimg.hh> # include <cstdint> # include <cstdlib> -# include <fcntl.h> # include <fmt/core.h> # include <string> -# include <sys/types.h> # include <thread> -# include <unistd.h> -# include <vector> -# include <webp/encode.h> -# include <webp/types.h> using namespace std::literals::string_literals; [[noreturn]] void benoit::main(int const argc,char const * * argv) noexcept { std::string const funcname = "benoit::main(int const,char const * *)"s; benoit::log(fmt::format("{}"s,argv[0x0])); benoit::logfunc(funcname); - benoit::dat.numthrds = std::thread::hardware_concurrency(); - benoit::log(fmt::format("{} availabe threads have been detected.",benoit::dat.numthrds)); + benoit::d::numthrds = std::thread::hardware_concurrency(); + benoit::log(fmt::format("{} availabe threads have been detected."s,benoit::d::numthrds)); benoit::arghandl(argc,argv); benoit::loadcfg(); - std::vector<std::uint8_t> buf = benoit::plotmandelbrot(); - benoit::exit(EXIT_SUCCESS); - std::string msg = ("P3 "s + std::to_string(benoit::dat.resx) + " "s +std::to_string(benoit::dat.resy) + " 255 "s); - for(auto val : buf) { - benoit::print(fmt::format("Found value {} in image."s,val)); - msg.append(std::to_string(val)); - msg.append(" "); - } - int file = ::open(benoit::dat.outimg.c_str(),O_WRONLY); - //for(::ssize_t bytesleft = msg.size();(bytesleft > 0x0);) { - if(::write(file,msg.c_str(),msg.size()) < 0x0) { - benoit::print(fmt::format("Unable to write to β{}β."s,benoit::dat.outimg)); - } - //} - if(::close(file) < 0x0) { - benoit::print(fmt::format("Unable to close file β{}β."s,benoit::dat.outimg)); - } + benoit::wrtimg(benoit::plotmandelbrot()); benoit::exit(EXIT_SUCCESS); } - /* - auto webpconf = ::WebPConfig(); - webpconf.lossless = 0x1; - webpconf.quality = 0x64; - webpconf.method = 0x6; - webpconf.segments = 0x4; - webpconf.sns_strength = 0x4; - webpconf.filter_strength = 0x0; - webpconf.filter_sharpness = 0x0; - webpconf.autofilter = 0x0; - webpconf.alpha_compression = 0x1; - webpconf.alpha_filtering = 0x2; - webpconf.alpha_quality = 0x64; - webpconf.pass = 0xA; - webpconf.preprocessing = 0x1; - webpconf.partitions = 0x3; - webpconf.partitions = 0x0; - webpconf.use_sharp_yuv = 0x0; - auto conferr = ::WebPValidateConfig(&webpconf); - auto webpimg = ::WebPPicture(); - WebPPictureInit(&webpimg); - webpimg.use_argb = 0x1; - webpimg.resx = 0x1; - webpimg.resy = 0x1; - WebPPictureAlloc(&webpimg); - auto webpmemwrit = WebPMemoryWriter(); - WebPMemoryWriterInit(&webpmemwrit); - webpimg.writer = WebPMemoryWrite; - webpimg.custom_ptr = &webpmemwrit; - webpimg.argb = {0xFF,0xFF,0x0,0x0}; - if(WebPEncode(&webpconf,&webpimg) == 0x0) { - } - else { - - } - WebPPictureFree(&webpimg); - auto buf = std::vector<std::uint8_t>(); - buf.push_back(0xFF); - buf.push_back(0x0); - buf.push_back(0x0); - auto file = std::fstream(benoit::outimt,std::fstream::binary | std::fstream::out | std::fstream::trunc); - if(!file.is_open()) { - ::_exit(EXIT_FAILURE); - } - const double maxR = 2.25; - const double minR = -2.25; - const double maxI = 2.25; - const double minI = -2.25; - - for(unsigned int y = 0; y < benoit::dat.resy; ++y) - for(unsigned int x = 0; x < benoit::dat.resx; ++x) { - long double r = x * ((maxR + benoit::real * benoit::dat.zoom) / benoit::dat.zoom - (minR + benoit::real * benoit::dat.zoom) / benoit::dat.zoom) / benoit::dat.resx + (minR + benoit::real * benoit::dat.zoom) / benoit::dat.zoom; - long double i = y * ((maxI + benoit::imag * benoit::dat.zoom) / benoit::dat.zoom - (minI + benoit::imag * benoit::dat.zoom) / benoit::dat.zoom) / benoit::dat.resx + (minI + benoit::imag * benoit::dat.zoom) / benoit::dat.zoom; - long double r2 = 0.0; - long double i2 = 0.0; - - unsigned int iter; - for(iter = 0; iter < benoit::maxiter; ++iter) { - if(r2 * r2 + i2 * i2 >= 4.0) - break; - - long double r2Temp = r2 * r2 - i2 * i2 + r; - long double i2Temp = 2.0 * r2 * i2 + i; - - if(r2 == r2Temp && i2 == i2Temp) { - iter = benoit::maxiter; - break; - } - - r2 = r2Temp; - i2 = i2Temp; - } - - std::uint8_t blue = 0x0; - std::uint8_t green = 0x0; - std::uint8_t red = 0x0; - - if(iter != benoit::maxiter) { - float tmp = ((float)(iter) / (float)(benoit::maxiter)); - blue = (std::uint8_t)((1.0 - tmp) * 255.0); - green = (std::uint8_t)((1.0 - tmp) * 255.0); - red = (std::uint8_t)((1.0 - tmp) * 255.0); - //double t = (double)(iter) / (double)(benoit::maxiter); - //red = (int)(8.0 * (1.0 - t) * t * t * t * 255.0); - //green = (int)(16.0 * (1.0 - t) * (1.0 - t) * t * t * 255.0); - //blue = (int)(8.0 * (1.0 - t) * (1.0 - t) * (1.0 - t) * t * 255.0); - } - buf.push_back(blue); - buf.push_back(green); - buf.push_back(red); - } -*/ diff --git a/src/benoit/plotmandelbrot.cc b/src/benoit/plotmandelbrot.cc index 36ea5b8..eb02ee9 100644 --- a/src/benoit/plotmandelbrot.cc +++ b/src/benoit/plotmandelbrot.cc @@ -1,11 +1,16 @@ -# include <benoit/dat.hh> +# include <benoit/d/numthrds.hh> +# include <benoit/d/pos.hh> +# include <benoit/d/resx.hh> +# include <benoit/d/resy.hh> # include <benoit/log.hh> # include <benoit/logfunc.hh> # include <benoit/logfuncret.hh> # include <benoit/plotmandelbrot.hh> # include <benoit/print.hh> # include <benoit/t/thrddat.hh> +# include <benoit/t/rgba.hh> # include <boost/multiprecision/mpfr.hpp> +# include <cassert> # include <cstdint> # include <fmt/core.h> # include <pthread.h> @@ -14,39 +19,106 @@ using namespace std::literals::string_literals; namespace { void * plotarea(void * thrddatptr) { - benoit::t::thrddat thrddat = *reinterpret_cast<benoit::t::thrddat *>(thrddatptr); - thrddat.img = new std::vector<std::uint8_t>; + benoit::t::thrddat * thrddat = reinterpret_cast<benoit::t::thrddat *>(thrddatptr); + for(unsigned long long px = *thrddat->imgbegin;(px <= *thrddat->imgend);++px) { + thrddat->img[px].r = *thrddat->thrdcol; + thrddat->img[px].g = *thrddat->thrdcol; + thrddat->img[px].b = *thrddat->thrdcol; + } pthread_exit(nullptr); } } -std::vector<std::uint8_t> benoit::plotmandelbrot() { +std::vector<std::uint8_t> * benoit::plotmandelbrot() { std::string const funcname = "benoit::plotmandelbrot()"s; benoit::logfunc(funcname); - std::vector<std::uint8_t> img; - unsigned short remainrows = benoit::dat.resy; - std::vector<benoit::t::thrddat> thrds; - for(unsigned thrdid = 0x0;(thrdid < benoit::dat.numthrds);++thrdid) { - thrds.emplace_back(); - thrds[thrdid].id = new unsigned(thrdid); - if((thrdid + 0x1) == benoit::dat.numthrds) { - thrds[thrdid].rows = new unsigned(remainrows); + unsigned long long const numpx = (benoit::d::resx * benoit::d::resy); + benoit::log(fmt::format("The image has a total of {} pixels."s,numpx)); + unsigned long long remainpx = numpx; + benoit::t::rgba * rgbaimg = ::new benoit::t::rgba[numpx]; + std::vector<benoit::t::thrddat> thrds(benoit::d::numthrds); + for(unsigned thrdid = 0x0;(thrdid < benoit::d::numthrds);++thrdid) { + thrds[thrdid].id = ::new unsigned(thrdid); + thrds[thrdid].img = rgbaimg; + thrds[thrdid].imgbegin = ::new unsigned long long(numpx / benoit::d::numthrds * thrdid); + if((thrdid + 0x1) == benoit::d::numthrds) { + thrds[thrdid].imgend = ::new unsigned long long(*thrds[thrdid].imgbegin + remainpx); } else { - thrds[thrdid].rows = new unsigned(benoit::dat.resy / benoit::dat.numthrds); + thrds[thrdid].imgend = ::new unsigned long long(*thrds[thrdid].imgbegin + numpx / benoit::d::numthrds); } - remainrows -= *thrds[thrdid].rows; - thrds[thrdid].thrd = new pthread_t; + --*thrds[thrdid].imgend; + assert(*thrds[thrdid].imgend <= numpx); + remainpx -= (*thrds[thrdid].imgend - *thrds[thrdid].imgbegin + 0x1); + thrds[thrdid].thrdcol = ::new std::uint8_t((float)(thrdid + 0x1) / (float)(benoit::d::numthrds) * 0xFFp0); + thrds[thrdid].thrd = ::new pthread_t; + benoit::log(fmt::format("Thread #{} will render a total of {} pixels, starting at position {} and ending at position {}, each with the colour {}, which means there are {} pixels remaining."s,thrdid,(*thrds[thrdid].imgend - *thrds[thrdid].imgbegin + 0x1),*thrds[thrdid].imgbegin,*thrds[thrdid].imgend,*thrds[thrdid].thrdcol,remainpx)); ::pthread_create(thrds[thrdid].thrd,nullptr,::plotarea,&thrds[thrdid]); - benoit::log(fmt::format("Thread #{} has been created."s,thrdid)); } for(auto thrd : thrds) { ::pthread_join(*thrd.thrd,nullptr); - benoit::log(fmt::format("Thread #{} has joined."s,*thrd.id)); - delete thrd.id; - delete thrd.img; - delete thrd.rows; - delete thrd.thrd; + benoit::log(fmt::format("Thread #{}, which coloured it's pixels with {}, has joined."s,*thrd.id,*thrd.thrdcol)); + ::delete thrd.id; + ::delete thrd.imgbegin; + ::delete thrd.imgend; + ::delete thrd.thrd; + ::delete thrd.thrdcol; + } + std::vector<std::uint8_t> * img = ::new std::vector<std::uint8_t>; + for(unsigned long long pos = 0x0ull;(pos < numpx);++pos) { + img->push_back(rgbaimg[pos].r); + img->push_back(rgbaimg[pos].g); + img->push_back(rgbaimg[pos].b); } + ::delete rgbaimg; benoit::logfuncret(funcname); return img; } +/* +const double maxR = 2.25; +const double minR = -2.25; +const double maxI = 2.25; +const double minI = -2.25; + +for(unsigned int y = 0; y < benoit::d::resy; ++y) + for(unsigned int x = 0; x < benoit::d::resx; ++x) { + long double r = x * ((maxR + benoit::real * benoit::d::zoom) / benoit::d::zoom - (minR + benoit::real * benoit::d::zoom) / benoit::d::zoom) / benoit::d::resx + (minR + benoit::real * benoit::d::zoom) / benoit::d::zoom; + long double i = y * ((maxI + benoit::imag * benoit::d::zoom) / benoit::d::zoom - (minI + benoit::imag * benoit::d::zoom) / benoit::d::zoom) / benoit::d::resx + (minI + benoit::imag * benoit::d::zoom) / benoit::d::zoom; + long double r2 = 0.0; + long double i2 = 0.0; + + unsigned int iter; + for(iter = 0; iter < benoit::maxiter; ++iter) { + if(r2 * r2 + i2 * i2 >= 4.0) + break; + + long double r2Temp = r2 * r2 - i2 * i2 + r; + long double i2Temp = 2.0 * r2 * i2 + i; + + if(r2 == r2Temp && i2 == i2Temp) { + iter = benoit::maxiter; + break; + } + + r2 = r2Temp; + i2 = i2Temp; + } + + std::uint8_t blue = 0x0; + std::uint8_t green = 0x0; + std::uint8_t red = 0x0; + + if(iter != benoit::maxiter) { + float tmp = ((float)(iter) / (float)(benoit::maxiter)); + blue = (std::uint8_t)((1.0 - tmp) * 255.0); + green = (std::uint8_t)((1.0 - tmp) * 255.0); + red = (std::uint8_t)((1.0 - tmp) * 255.0); + //double t = (double)(iter) / (double)(benoit::maxiter); + //red = (int)(8.0 * (1.0 - t) * t * t * t * 255.0); + //green = (int)(16.0 * (1.0 - t) * (1.0 - t) * t * t * 255.0); + //blue = (int)(8.0 * (1.0 - t) * (1.0 - t) * (1.0 - t) * t * 255.0); + } + buf.push_back(blue); + buf.push_back(green); + buf.push_back(red); + } +*/ diff --git a/src/benoit/print.cc b/src/benoit/print.cc index ab9547c..e1488bd 100644 --- a/src/benoit/print.cc +++ b/src/benoit/print.cc @@ -1,30 +1,27 @@ -# include <benoit/dat.hh> +# include <benoit/d/thelog.hh> +# include <benoit/d/printdolog.hh> # include <benoit/print.hh> # include <fcntl.h> # include <stdexcept> # include <string> # include <unistd.h> +using namespace std::literals::string_literals; void benoit::print(char const * msg,bool stderr) { - std::string const funcname = "benoit::print(char const *)"s; + std::string const funcname = "benoit::print(char const *,bool)"s; benoit::print(std::string(msg),stderr); } void benoit::print(std::string msg,bool stderr) { - std::string const funcname = "benoit::print(std::string)"s; - if(benoit::dat.printdolog) { - benoit::dat.thelog.insert(benoit::dat.thelog.begin(),msg); + std::string const funcname = "benoit::print(std::string,bool)"s; + if(benoit::d::printdolog) { + benoit::d::thelog.insert(benoit::d::thelog.begin(),msg); } + msg.append("\u000A"s); int file = 0x0; if(stderr) { - ::open("/dev/stderr",O_WRONLY); + file = 0x1; } - else { - ::open("/dev/stdout",O_WRONLY); - } - msg.append("\u000A"); if(::write(file,msg.c_str(),msg.size()) < 0x0) { throw std::runtime_error("Unable to write to Stdout."); } - if(::close(file) < 0x0) { - throw std::runtime_error("Unable to close Stdout"); - } + fsync(file); } diff --git a/src/benoit/wrtimg.cc b/src/benoit/wrtimg.cc new file mode 100644 index 0000000..8a38ee9 --- /dev/null +++ b/src/benoit/wrtimg.cc @@ -0,0 +1,96 @@ +# include <benoit/d/imgfmt.hh> +# include <benoit/d/outimg.hh> +# include <benoit/d/resx.hh> +# include <benoit/d/resy.hh> +# include <benoit/logfunc.hh> +# include <benoit/logfuncret.hh> +# include <benoit/print.hh> +# include <benoit/t/imgfmt.hh> +# include <benoit/wrtimg.hh> +# include <cstdint> +# include <cstdlib> +# include <fcntl.h> +# include <fmt/core.h> +# include <png.h> +# include <string> +# include <sys/types.h> +# include <unistd.h> +# include <vector> +# include <webp/encode.h> +# include <webp/types.h> +using namespace std::literals::string_literals; +void benoit::wrtimg(std::vector<std::uint8_t> * img) { + std::string const funcname = "benoit::wrtimg(std::vector<std::uint8_t> *)"s; + benoit::logfunc(funcname); + std::uint8_t * dat; + unsigned long long datsiz; + switch(benoit::d::imgfmt) { + case benoit::t::imgfmt::png: + break; + case benoit::t::imgfmt::webp: + datsiz = WebPEncodeLosslessRGB(img->data(),benoit::d::resx,benoit::d::resy,(benoit::d::resy * 0x3),&dat); + break; + } + int file = ::open(benoit::d::outimg.c_str(),O_TRUNC | O_WRONLY); + auto iterwrt = [](int & file,std::uint8_t * & dat,unsigned long long & datsiz) { + for(unsigned long long pos = 0x0;(pos < datsiz);++pos) { + ::ssize_t byteswrtn = ::write(file,&dat[pos],0x1); + if(byteswrtn < 0x0) { + benoit::print(fmt::format("Unable to write to β{}β."s,benoit::d::outimg)); + return; + } + } + }; + iterwrt(file,dat,datsiz); + delete dat; + delete img; + if(::close(file) < 0x0) { + benoit::print(fmt::format("Unable to close file β{}β."s,benoit::d::outimg)); + } + benoit::logfuncret(funcname); +} +/* +auto webpconf = ::WebPConfig(); +webpconf.lossless = 0x1; +webpconf.quality = 0x64; +webpconf.method = 0x6; +webpconf.segments = 0x4; +webpconf.sns_strength = 0x4; +webpconf.filter_strength = 0x0; +webpconf.filter_sharpness = 0x0; +webpconf.autofilter = 0x0; +webpconf.alpha_compression = 0x1; +webpconf.alpha_filtering = 0x2; +webpconf.alpha_quality = 0x64; +webpconf.pass = 0xA; +webpconf.preprocessing = 0x1; +webpconf.partitions = 0x3; +webpconf.partitions = 0x0; +webpconf.use_sharp_yuv = 0x0; +auto conferr = ::WebPValidateConfig(&webpconf); +auto webpimg = ::WebPPicture(); +WebPPictureInit(&webpimg); +webpimg.use_argb = 0x1; +webpimg.resx = 0x1; +webpimg.resy = 0x1; +WebPPictureAlloc(&webpimg); +auto webpmemwrit = WebPMemoryWriter(); +WebPMemoryWriterInit(&webpmemwrit); +webpimg.writer = WebPMemoryWrite; +webpimg.custom_ptr = &webpmemwrit; +webpimg.argb = {0xFF,0xFF,0x0,0x0}; +if(WebPEncode(&webpconf,&webpimg) == 0x0) { +} +else { + +} +WebPPictureFree(&webpimg); +auto buf = std::vector<std::uint8_t>(); +buf.push_back(0xFF); +buf.push_back(0x0); +buf.push_back(0x0); +auto file = std::fstream(benoit::outimt,std::fstream::binary | std::fstream::out | std::fstream::trunc); +if(!file.is_open()) { + ::_exit(EXIT_FAILURE); +} +*/ |