channel.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 373 行

CPP
373
字号
/*    Copyright 2005-2007 Adobe Systems Incorporated       Use, modification and distribution are subject to 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).    See http://opensource.adobe.com/gil for most recent version including documentation.*/// channel.cpp : Tests channel//#include <exception>#include <boost/gil/gil_config.hpp>#include <boost/gil/channel_algorithm.hpp>#include <boost/gil/gil_concept.hpp>using namespace boost::gil;using namespace std;void error_if(bool);bits8   c8_min   =  channel_traits<bits8  >::min_value();bits8   c8_max   =  channel_traits<bits8  >::max_value();bits8s  c8s_min  =  channel_traits<bits8s >::min_value();bits8s  c8s_max  =  channel_traits<bits8s >::max_value();bits16  c16_min  =  channel_traits<bits16 >::min_value();bits16  c16_max  =  channel_traits<bits16 >::max_value();bits16s c16s_min =  channel_traits<bits16s>::min_value();bits16s c16s_max =  channel_traits<bits16s>::max_value();bits32  c32_min  =  channel_traits<bits32 >::min_value();bits32  c32_max  =  channel_traits<bits32 >::max_value();bits32s c32s_min =  channel_traits<bits32s>::min_value();bits32s c32s_max =  channel_traits<bits32s>::max_value();bits32f c32f_min =  channel_traits<bits32f>::min_value();bits32f c32f_max =  channel_traits<bits32f>::max_value();template <typename ChannelTestCore>struct do_test : public ChannelTestCore {    typedef typename ChannelTestCore::channel_t channel_t;    typedef typename channel_traits<channel_t>::value_type channel_value_t;    do_test() : ChannelTestCore() {        error_if(this->_min_v != channel_traits<channel_t>::min_value());        error_if(this->_max_v != channel_traits<channel_t>::max_value());    }    void test_all() {        test_channel_invert();        test_channel_convert();        test_channel_multiply();        test_channel_math();    }    void test_mutable(boost::mpl::false_) {}    void test_mutable(boost::mpl::true_) {        channel_value_t mv=this->_min_v;        ++this->_min_v; this->_min_v++;        --this->_min_v; this->_min_v--;        error_if(mv!=this->_min_v);        this->_min_v+=1;        this->_min_v-=1;        error_if(mv!=this->_min_v);        this->_min_v*=1;        this->_min_v/=1;        error_if(mv!=this->_min_v);         this->_min_v = 1;    // assignable to scalar         this->_min_v = mv;   // and to value type         // test swap         channel_value_t v1=this->_min_v;         channel_value_t v2=this->_max_v;         swap(this->_min_v, this->_max_v);         channel_value_t v3=this->_min_v;         channel_value_t v4=this->_max_v;         error_if(v1!=v4 || v2!=v3);    }    void test_channel_math() {        error_if(this->_min_v >= this->_max_v);        error_if(this->_max_v <= this->_min_v);        error_if(this->_min_v > this->_max_v);        error_if(this->_max_v < this->_min_v);        error_if(this->_max_v == this->_min_v);        error_if(!(this->_max_v != this->_min_v));        error_if(this->_min_v * 1 != this->_min_v);        error_if(this->_min_v / 1 != this->_min_v);        error_if((this->_min_v + 1) + 1 != (this->_min_v + 2));        error_if((this->_max_v - 1) - 1 != (this->_max_v - 2));        error_if(this->_min_v != 1 && this->_min_v==1);  // comparable to integral        test_mutable(boost::mpl::bool_<channel_traits<channel_t>::is_mutable>());    }    void test_channel_invert() {        error_if(channel_invert(this->_min_v) != this->_max_v);        error_if(channel_invert(this->_max_v) != this->_min_v);    }    void test_channel_multiply() {        error_if(channel_multiply(this->_min_v, this->_min_v) != this->_min_v);        error_if(channel_multiply(this->_max_v, this->_max_v) != this->_max_v);        error_if(channel_multiply(this->_max_v, this->_min_v) != this->_min_v);    }    void test_channel_convert() {        channel_value_t  v_min, v_max;        v_min=channel_convert<channel_t>(c8_min);        v_max=channel_convert<channel_t>(c8_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);        v_min=channel_convert<channel_t>(c8s_min);        v_max=channel_convert<channel_t>(c8s_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);        v_min=channel_convert<channel_t>(c16_min);        v_max=channel_convert<channel_t>(c16_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);        v_min=channel_convert<channel_t>(c16s_min);        v_max=channel_convert<channel_t>(c16s_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);        v_min=channel_convert<channel_t>(c32_min);        v_max=channel_convert<channel_t>(c32_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);        v_min=channel_convert<channel_t>(c32s_min);        v_max=channel_convert<channel_t>(c32s_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);        v_min=channel_convert<channel_t>(c32f_min);        v_max=channel_convert<channel_t>(c32f_max);        error_if(v_min!=this->_min_v || v_max!=this->_max_v);    }};// Different core classes depending on the different types of channels - channel values, references and subbyte references// The cores ensure there are two members, _min_v and _max_v initialized with the minimum and maximum channel value.// The different channel types have different ways to initialize them, thus require different cores// For channel values simply initialize the value directlytemplate <typename ChannelValue>class value_core {protected:    typedef ChannelValue channel_t;    channel_t _min_v, _max_v;    value_core() : _min_v(channel_traits<ChannelValue>::min_value()), _max_v(channel_traits<ChannelValue>::max_value()) {        boost::function_requires<ChannelValueConcept<ChannelValue> >();    }};// For channel references we need to have separate channel valuestemplate <typename ChannelRef>class reference_core : public value_core<typename channel_traits<ChannelRef>::value_type> {    typedef value_core<typename channel_traits<ChannelRef>::value_type> parent_t;protected:    typedef ChannelRef channel_t;    channel_t _min_v, _max_v;    reference_core() : parent_t(), _min_v(parent_t::_min_v), _max_v(parent_t::_max_v) {        boost::function_requires<ChannelConcept<ChannelRef> >();    }};// For subbyte channel references we need to store the bit buffers somewheretemplate <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>class packed_reference_core {protected:    typedef ChannelSubbyteRef channel_t;    typedef typename channel_t::integer_t integer_t;    channel_t _min_v, _max_v;    integer_t _min_buf, _max_buf;    packed_reference_core() : _min_v(&_min_buf), _max_v(&_max_buf) {        ChannelMutableRef b1(&_min_buf), b2(&_max_buf);        b1 = channel_traits<channel_t>::min_value();        b2 = channel_traits<channel_t>::max_value();        boost::function_requires<ChannelConcept<ChannelSubbyteRef> >();    }};template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>class packed_dynamic_reference_core {protected:    typedef ChannelSubbyteRef channel_t;    channel_t _min_v, _max_v;    typename channel_t::integer_t _min_buf, _max_buf;    packed_dynamic_reference_core(int first_bit1=1, int first_bit2=2) : _min_v(&_min_buf,first_bit1), _max_v(&_max_buf,first_bit2) {        ChannelMutableRef b1(&_min_buf,1), b2(&_max_buf,2);        b1 = channel_traits<channel_t>::min_value();        b2 = channel_traits<channel_t>::max_value();        boost::function_requires<ChannelConcept<ChannelSubbyteRef> >();    }};template <typename ChannelValue>void test_channel_value() {     do_test<value_core<ChannelValue> >().test_all();}template <typename ChannelRef>void test_channel_reference() {     do_test<reference_core<ChannelRef> >().test_all();}template <typename ChannelSubbyteRef>void test_packed_channel_reference() {    do_test<packed_reference_core<ChannelSubbyteRef,ChannelSubbyteRef> >().test_all();}template <typename ChannelSubbyteRef, typename MutableRef>void test_const_packed_channel_reference() {    do_test<packed_reference_core<ChannelSubbyteRef,MutableRef> >().test_all();}template <typename ChannelSubbyteRef>void test_packed_dynamic_channel_reference() {    do_test<packed_dynamic_reference_core<ChannelSubbyteRef,ChannelSubbyteRef> >().test_all();}template <typename ChannelSubbyteRef, typename MutableRef>void test_const_packed_dynamic_channel_reference() {    do_test<packed_dynamic_reference_core<ChannelSubbyteRef,MutableRef> >().test_all();}template <typename ChannelValue>void test_channel_value_impl() {    test_channel_value<ChannelValue>();    test_channel_reference<ChannelValue&>();    test_channel_reference<const ChannelValue&>();}/////////////////////////////////////////////////////////////// A channel archetype - to test the minimum requirements of the concept////////////////////////////////////////////////////////////struct channel_value_archetype;struct channel_archetype {    // equality comparable    friend bool operator==(const channel_archetype&,const channel_archetype&) { return true; }    friend bool operator!=(const channel_archetype&,const channel_archetype&) { return false; }    // less-than comparable    friend bool operator<(const channel_archetype&,const channel_archetype&) { return false; }    // convertible to a scalar    operator bits8() const { return 0; }        channel_archetype& operator++() { return *this; }    channel_archetype& operator--() { return *this; }    channel_archetype  operator++(int) { return *this; }    channel_archetype  operator--(int) { return *this; }        template <typename Scalar> channel_archetype operator+=(Scalar) { return *this; }    template <typename Scalar> channel_archetype operator-=(Scalar) { return *this; }    template <typename Scalar> channel_archetype operator*=(Scalar) { return *this; }    template <typename Scalar> channel_archetype operator/=(Scalar) { return *this; }    typedef channel_value_archetype         value_type;    typedef channel_archetype               reference;    typedef const channel_archetype         const_reference;    typedef channel_value_archetype*        pointer;    typedef const channel_value_archetype*  const_pointer;    BOOST_STATIC_CONSTANT(bool, is_mutable=true);    static value_type min_value();    static value_type max_value();};struct channel_value_archetype : public channel_archetype {    channel_value_archetype() {}                                        // default constructible    channel_value_archetype(const channel_value_archetype&) {}          // copy constructible    channel_value_archetype& operator=(const channel_value_archetype&){return *this;} // assignable    channel_value_archetype(bits8) {}};channel_value_archetype channel_archetype::min_value() { return channel_value_archetype(); }channel_value_archetype channel_archetype::max_value() { return channel_value_archetype(); }void test_packed_channel_reference() {    typedef packed_channel_reference<boost::uint16_t, 0,5,true> channel16_0_5_reference_t;    typedef packed_channel_reference<boost::uint16_t, 5,6,true> channel16_5_6_reference_t;    typedef packed_channel_reference<boost::uint16_t, 11,5,true> channel16_11_5_reference_t;    boost::uint16_t data=0;    channel16_0_5_reference_t   channel1(&data);    channel16_5_6_reference_t   channel2(&data);    channel16_11_5_reference_t  channel3(&data);    channel1=channel_traits<channel16_0_5_reference_t>::max_value();    channel2=channel_traits<channel16_5_6_reference_t>::max_value();    channel3=channel_traits<channel16_11_5_reference_t>::max_value();    error_if(data!=65535);    test_packed_channel_reference<channel16_0_5_reference_t>();    test_packed_channel_reference<channel16_5_6_reference_t>();    test_packed_channel_reference<channel16_11_5_reference_t>();}void test_packed_dynamic_channel_reference() {    typedef packed_dynamic_channel_reference<boost::uint16_t,5,true> channel16_5_reference_t;    typedef packed_dynamic_channel_reference<boost::uint16_t,6,true> channel16_6_reference_t;    boost::uint16_t data=0;    channel16_5_reference_t  channel1(&data,0);    channel16_6_reference_t  channel2(&data,5);    channel16_5_reference_t  channel3(&data,11);    channel1=channel_traits<channel16_5_reference_t>::max_value();    channel2=channel_traits<channel16_6_reference_t>::max_value();    channel3=channel_traits<channel16_5_reference_t>::max_value();    error_if(data!=65535);    test_packed_dynamic_channel_reference<channel16_5_reference_t>();}void test_channel() {    test_channel_value_impl<bits8>();    test_channel_value_impl<bits8s>();    test_channel_value_impl<bits16>();    test_channel_value_impl<bits16s>();    test_channel_value_impl<bits32>();    test_channel_value_impl<bits32s>();    test_channel_value_impl<bits32f>();    test_packed_channel_reference();    test_packed_dynamic_channel_reference();    // Do only compile-time tests for the archetype (because asserts like val1<val2 fail)    boost::function_requires<MutableChannelConcept<channel_archetype> >();    do_test<value_core<channel_value_archetype> >();    do_test<reference_core<channel_archetype> >();    do_test<reference_core<const channel_archetype&> >();}int main(int argc, char* argv[]) {    test_channel();    return 0;}// TODO: // - provide algorithm performance overloads for scoped channel and packed channels// - Update concepts and documentation// - What to do about pointer types?!// - Performance!!//      - is channel_convert the same as native?//      - is operator++ on bits32f the same as native? How about if operator++ is defined in scoped_channel to do _value++?

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?