| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 | //// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev//// Distributed under the Boost Software License, Version 1.0// See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt//#ifndef BOOST_GIL_IO_BIT_OPERATIONS_HPP#define BOOST_GIL_IO_BIT_OPERATIONS_HPP#include <boost/gil/io/typedefs.hpp>#include <array>#include <cstddef>#include <type_traits>namespace boost { namespace gil { namespace detail {// 1110 1100 -> 0011 0111template <typename Buffer, typename IsBitAligned>struct mirror_bits{    mirror_bits(bool) {};    void operator()(Buffer&) {}    void operator()(byte_t*, std::size_t){}};// The functor will generate a lookup table since the// mirror operation is quite costly.template <typename Buffer>struct mirror_bits<Buffer, std::true_type>{    mirror_bits(bool apply_operation = true)        : apply_operation_(apply_operation)    {        if(apply_operation_)        {            byte_t i = 0;            do            {                lookup_[i] = mirror(i);            }            while (i++ != 255);        }   }    void operator()(Buffer& buffer)    {        if (apply_operation_)            for_each(buffer.begin(), buffer.end(), [this](byte_t& c) { lookup(c); });    }    void operator()(byte_t *dst, std::size_t size)    {        for (std::size_t i = 0; i < size; ++i)        {            lookup(*dst);            ++dst;        }    }private:    void lookup(byte_t& c)    {        c = lookup_[c];    }    static byte_t mirror(byte_t c)    {        byte_t result = 0;        for (int i = 0; i < 8; ++i)        {            result = result << 1;            result |= (c & 1);            c = c >> 1;        }        return result;    }    std::array<byte_t, 256> lookup_;    bool apply_operation_;};// 0011 1111 -> 1100 0000template <typename Buffer, typename IsBitAligned>struct negate_bits{    void operator()(Buffer&) {};};template <typename Buffer>struct negate_bits<Buffer, std::true_type>{    void operator()(Buffer& buffer)    {        for_each(buffer.begin(), buffer.end(),            negate_bits<Buffer, std::true_type>::negate);    }    void operator()(byte_t* dst, std::size_t size)    {        for (std::size_t i = 0; i < size; ++i)        {            negate(*dst);            ++dst;        }    }private:    static void negate(byte_t& b)    {        b = ~b;    }};// 11101100 -> 11001110template <typename Buffer, typename IsBitAligned>struct swap_half_bytes{    void operator()(Buffer&) {};};template <typename Buffer>struct swap_half_bytes<Buffer, std::true_type>{    void operator()(Buffer& buffer)    {        for_each(buffer.begin(), buffer.end(),            swap_half_bytes<Buffer, std::true_type>::swap);    }    void operator()(byte_t* dst, std::size_t size)    {        for (std::size_t i = 0; i < size; ++i)        {            swap(*dst);            ++dst;        }    }private:    static void swap(byte_t& c)    {        c = ((c << 4) & 0xF0) | ((c >> 4) & 0x0F);    }};template <typename Buffer>struct do_nothing{   do_nothing() = default;   void operator()(Buffer&) {}};/// Count consecutive zeros on the righttemplate <typename T>inline unsigned int trailing_zeros(T x) noexcept{    unsigned int n = 0;    x = ~x & (x - 1);    while (x)    {        n = n + 1;        x = x >> 1;    }    return n;}/// Counts ones in a bit-settemplate <typename T>inlineunsigned int count_ones(T x) noexcept{    unsigned int n = 0;    while (x)    {        // clear the least significant bit set        x &= x - 1;        ++n;    }    return n;}}}} // namespace boost::gil::detail#endif
 |