From ad38bc6ecb80ddeb562841b33258dd53659b1da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 24 Aug 2020 18:44:51 +0200 Subject: New upstream version 1.0.31 --- backend/genesys/utilities.h | 138 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) (limited to 'backend/genesys/utilities.h') diff --git a/backend/genesys/utilities.h b/backend/genesys/utilities.h index 1e268b5..fdab770 100644 --- a/backend/genesys/utilities.h +++ b/backend/genesys/utilities.h @@ -46,12 +46,81 @@ #include "error.h" #include +#include #include #include #include + namespace genesys { +// just like SANE_FIX and SANE_UNFIX except that the conversion is done by a function and argument +// precision is handled correctly +inline SANE_Word double_to_fixed(double v) +{ + return static_cast(v * (1 << SANE_FIXED_SCALE_SHIFT)); +} + +inline SANE_Word float_to_fixed(float v) +{ + return static_cast(v * (1 << SANE_FIXED_SCALE_SHIFT)); +} + +inline float fixed_to_float(SANE_Word v) +{ + return static_cast(v) / (1 << SANE_FIXED_SCALE_SHIFT); +} + +inline double fixed_to_double(SANE_Word v) +{ + return static_cast(v) / (1 << SANE_FIXED_SCALE_SHIFT); +} + +template +inline T abs_diff(T a, T b) +{ + if (a < b) { + return b - a; + } else { + return a - b; + } +} + +inline std::uint64_t align_multiple_floor(std::uint64_t x, std::uint64_t multiple) +{ + if (multiple == 0) { + return x; + } + return (x / multiple) * multiple; +} + +inline std::uint64_t align_multiple_ceil(std::uint64_t x, std::uint64_t multiple) +{ + if (multiple == 0) { + return x; + } + return ((x + multiple - 1) / multiple) * multiple; +} + +inline std::uint64_t multiply_by_depth_ceil(std::uint64_t pixels, std::uint64_t depth) +{ + if (depth == 1) { + return (pixels / 8) + ((pixels % 8) ? 1 : 0); + } else { + return pixels * (depth / 8); + } +} + +template +inline T clamp(const T& value, const T& lo, const T& hi) +{ + if (value < lo) + return lo; + if (value > hi) + return hi; + return value; +} + template void compute_array_percentile_approx(T* result, const T* data, std::size_t line_count, std::size_t elements_per_line, @@ -85,6 +154,75 @@ void compute_array_percentile_approx(T* result, const T* data, } } +class Ratio +{ +public: + Ratio() : multiplier_{1}, divisor_{1} + { + } + + Ratio(unsigned multiplier, unsigned divisor) : multiplier_{multiplier}, divisor_{divisor} + { + } + + unsigned multiplier() const { return multiplier_; } + unsigned divisor() const { return divisor_; } + + unsigned apply(unsigned arg) const + { + return static_cast(arg) * multiplier_ / divisor_; + } + + int apply(int arg) const + { + return static_cast(arg) * multiplier_ / divisor_; + } + + float apply(float arg) const + { + return arg * multiplier_ / divisor_; + } + + unsigned apply_inverse(unsigned arg) const + { + return static_cast(arg) * divisor_ / multiplier_; + } + + int apply_inverse(int arg) const + { + return static_cast(arg) * divisor_ / multiplier_; + } + + float apply_inverse(float arg) const + { + return arg * divisor_ / multiplier_; + } + + bool operator==(const Ratio& other) const + { + return multiplier_ == other.multiplier_ && divisor_ == other.divisor_; + } +private: + unsigned multiplier_; + unsigned divisor_; + + template + friend void serialize(Stream& str, Ratio& x); +}; + +template +void serialize(Stream& str, Ratio& x) +{ + serialize(str, x.multiplier_); + serialize(str, x.divisor_); +} + +inline std::ostream& operator<<(std::ostream& out, const Ratio& ratio) +{ + out << ratio.multiplier() << "/" << ratio.divisor(); + return out; +} + template class BasicStreamStateSaver { -- cgit v1.2.3