LCOV - code coverage report
Current view: top level - src/AH/Math - IncreaseBitDepth.hpp (source / functions) Hit Total Coverage
Test: e224b347cd670555e44f06608ac41bd1ace9d9d8 Lines: 12 12 100.0 %
Date: 2020-09-08 17:44:46 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <AH/Settings/Warnings.hpp>
       4             : AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
       5             : 
       6             : #include <AH/STL/type_traits> // enable_if
       7             : #include <limits.h>           // CHAR_BIT
       8             : #include <stddef.h>           // size_t
       9             : 
      10             : BEGIN_AH_NAMESPACE
      11             : 
      12             : template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
      13             : std::enable_if_t<(Bits_out <= 2 * Bits_in), T_out>
      14             : increaseBitDepthImpl(T_in in);
      15             : 
      16             : template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
      17             : std::enable_if_t<(Bits_out > 2 * Bits_in), T_out>
      18           8 : increaseBitDepthImpl(T_in in) {
      19           8 :     constexpr size_t leftShift = Bits_out - Bits_in;
      20          24 :     return (T_out(in) << leftShift) |
      21           8 :            increaseBitDepthImpl<leftShift, Bits_in, T_out>(in);
      22           8 : }
      23             : 
      24             : template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
      25             : std::enable_if_t<(Bits_out <= 2 * Bits_in), T_out>
      26          82 : increaseBitDepthImpl(T_in in) {
      27          82 :     constexpr size_t leftShift = Bits_out - Bits_in;
      28          82 :     constexpr size_t rightShift = Bits_in - leftShift;
      29         164 :     return (T_out(in) << leftShift) | (in >> rightShift);
      30          82 : }
      31             : 
      32             : /// @addtogroup    AH_Math
      33             : /// @{
      34             : 
      35             : /**
      36             :  * @brief   Increase the bit depth of the given value from `Bits_in` bits wide
      37             :  *          to `Bits_out` bits wide, evenly distributing the error across the 
      38             :  *          entire range, such that the error for each element is between -0.5
      39             :  *          and +0.5.
      40             :  * 
      41             :  * For example, converting 3-bit numbers to 7-bit numbers would result in the
      42             :  * following:
      43             :  * 
      44             :  * | in (dec) | in (bin) | out (bin) | out (dec) | exact  | error |
      45             :  * |:--------:|:--------:|:---------:|:---------:|:------:|:-----:|
      46             :  * | 0        | 000      | 000'0000  | 0         | 0.00   | +0.00 |
      47             :  * | 1        | 001      | 001'0010  | 18        | 18.14  | +0.14 |
      48             :  * | 2        | 010      | 010'0100  | 36        | 36.29  | +0.29 |
      49             :  * | 3        | 011      | 011'0110  | 54        | 54.43  | +0.43 |
      50             :  * | 4        | 100      | 100'1001  | 73        | 72.57  | -0.43 |
      51             :  * | 5        | 101      | 101'1011  | 91        | 90.71  | -0.29 |
      52             :  * | 6        | 110      | 110'1101  | 109       | 108.86 | -0.14 |
      53             :  * | 7        | 111      | 111'1111  | 127       | 127.00 | +0.00 |
      54             :  * 
      55             :  * @tparam  Bits_out 
      56             :  *          The number of bits of the output range.
      57             :  * @tparam  Bits_in 
      58             :  *          The number of bits of the input range.
      59             :  * @tparam  T_out 
      60             :  *          The type of the output (return type).
      61             :  * @tparam  T_in 
      62             :  *          The type of the input.
      63             :  * @param   in 
      64             :  *          The value to scale up.
      65             :  * @return  The scaled up value.
      66             :  */
      67             : template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
      68          82 : T_out increaseBitDepth(T_in in) {
      69             :     static_assert(Bits_in <= sizeof(T_in) * CHAR_BIT,
      70             :                   "Error: Bits_in > bits(T_in)");
      71             :     static_assert(Bits_out <= sizeof(T_out) * CHAR_BIT,
      72             :                   "Error: Bits_out > bits(T_out)");
      73          82 :     return increaseBitDepthImpl<Bits_out, Bits_in, T_out>(in);
      74             : }
      75             : 
      76             : /// @}
      77             : 
      78             : END_AH_NAMESPACE
      79             : 
      80             : AH_DIAGNOSTIC_POP()

Generated by: LCOV version 1.14-6-g40580cd