GILɨ솖髒

׷՟:
Lubomir Bourdev (lbourdev@adobe.com) ꍠHailin Jin (hljin@adobe.com)
Adobe ϵͳ髖/dd>
঱/b>
2.1
ȕƚ:
September 15, 2007

GILʇһ趴Ӌ㷨퇶ȳ錚ͼϱ퓿ڵă++ꯊ,ᾎĵ僨ʶKGIL儉輆-Į. ᾎĵ嵄ĚȝԶԶ㬹큋ȧꎼⵥ儊鈴GIL˹Ҫ監ꊶ. ԚGIL監璳ɏ,ģԕҵ풻越鈴GIL兒싙ư壟http://opensource.adobe.com/gil

(ҫ՟ע:ᾎĖmage viewꍶiew㻬Ӄ,Ƥʵ˼C漊ǩmage view儺쒥.ΪK罱㬎҃Ǎ㒻ʹӃͼϱʓͼ)



1. 臘漯a>

ԚȎꎍ쏱䦀Ӿ庍ʓƵ䦀餳̖ͼϱ漊Ǻܻ鱾儸ń嫊Ǎ쏱Ԛ᭏։ϵć糧Ͳᰊ醬ˣ槏ꂫ꜄ї浽숍藪Ӗ蟐箠Ԛ᾽ږΒC芶һΒCaČ䕽.

Ԛςa儌ւۖͼϱ늓Ϊϱ˘儒븶2άʽש. ϱ˘ʇһ趑Չ덨倵ļﺏ, 夜퍼ϱ֐ָ樵㵄ѕɫ. y趍貲夜푕ɫש쾵Ē븶ֵ. 䦔ځ햖ͨӃ傻쏱Ě䦽ṹ. Interleavedͼϱ, ϱ˘ʇ療漱, ͨ伀Ǽ臨䦴ⵄ, 渰lanarͼϱ, ⻍쵄ͨ笨攚⻍쵄ѕɫaɏ. ςaʇһ趴x3 RGB Ѝ傻쏱,麼됐儵ڶϱ˘ự꼇Ϊꬉ묠ʇ interleaved Ѝ儺

interleaved.jpg
淵⸶ʇplanarЍ儺

planar.jpg

ҪעҢܵĐԆ뵼ւĩ兒հ׌.

GIL̡駔č쏱ģЍԓ涔ȧς儱仯:

  • 鐔(planar ꍠinterleaved)
  • ѕɫ亍alphaᭊRGB, RGBA, CMYK, 刵Ȯ)
  • ѕɫͨ倉 (8λ, 16λ, 刵Ȯ)
  • ͨ倵Ĵΐ⨒GB ꍠBGR, 刵Ȯ)
  • 攆벟” (uӐ攆묗ֶԆ묠刵Ȯ)

GIL빖糖Ӄ맶蒥傻쏱ģЍ,Ҕ찲Ί픚ԋʱָ樵č쏱 Ѝ. GIL䓋㷨儽Ƕȳ錚Kͼϱ儱폖, բѹ亂떻ʩһ䎬 ɒԊ閮餗甚跖֍쏱 Ѝɏ, 淵䲺ɺ兒ɖ䐐亂닙戩Ժ͕붔̘樍쏱 Ѝ儊֐䴺«Ϡ懃.

ᾎĵ拿ѭה楏≏儉輆ԭԲ. y횶蒥儸ńbԚɏһ횶蒥儸ńɏ. ͆춄㰴Օ횵Ĵΐ…悅巔


2. 闠ڃoncept

˹Ӑ儇IL鷫춼ʇGIL腄ģЍ. 腄ΪK纐͋㷨սȷ儓擃,һ趀Ѝ(법ߒ뗩Ϡ閥Ѝ)ᘐ낺ף儒뗩̵쾮 բ̵쾰쀨ӯ稐Ίˣ稔ˋ㮠=ȧ,GIL Ѝ pixel ʇ GIL 腄ixelConcept億㐍. Ӄ맿ɒԊ鈴ה캵ĀЍ̦뻼code>pixel. ֻҪ˼Ĝ黂ꗣPixelConcept儒ꇳ, ˹ӐƤ˻儇IL Ѝꍋ㷨漿ɒԊ鈴. բ/Ӑ輶ฅĮ儐ŏ⠼a href="http://www.generic-programming.org/languages/conceptcpp/">http://www.generic-programming.org/languages/conceptcpp/

ΒC鈴ӯ滋ĐΊҥ腄⊇C++0x ᪗춨ҥ儒븶闠ڸń)չ: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf

բ/Ӑ輶ൄGILʹӃ儸ńҥ,㲿疶씚բ/: http://www.generic-programming.org/languages/conceptcpp/concept_web.php

auto concept DefaultConstructible<typename T> {
    T::T();    
};

auto concept CopyConstructible<typename T> {
    T::T(T);
    T::~T();
};

auto concept Assignable<typename T, typename U = T> {
    typename result_type;
    result_type operator=(T&, U);    
};

auto concept EqualityComparable<typename T, typename U = T> {
    bool operator==(T x, T y);    
    bool operator!=(T x, T y) { return !(x==y); }
};

concept SameType<typename T, typename U> {  unspecified  };
template<typename T> concept_map SameType<T, T> {  unspecified  };

auto concept Swappable<typename T> {
    void swap(T& t, T& u);
};

բ/ʇ軾ӵćILҪ儻鱾腄p>

auto concept Regular<typename T> : DefaultConstructible<T>, CopyConstructible<T>, EqualityComparable<T>, Assignable<T>, Swappable<T> {};

auto concept Metafunction<typename T> {
    typename type;
};

3. 壼/a>

һ趵㶨ҥKͼϱ֐ϱ˘載떃, ˼ҲԓA䃨ʶͼϱ載춈. 䓗Ӄ儽Ƕȿ䬠壞ǎ-ά靚oףςP腄Ҫdz:

concept PointNDConcept<typename T> : Regular<T> {    
    // y趖ᵄ׸᪶蒥
    template <size_t K> struct axis; where Metafunction<axis>;
            
    const size_t num_dimensions;
    
    // 烎ʯ脠y趖ᵄʽֵ.
    template <size_t K> const typename axis<K>::type& T::axis_value() const;
    template <size_t K>       typename axis<K>::type& T::axis_value();
};

GIL ʹӃ2ά壬 ˼ʇ腄code>PointNDConcept 儒븶ǿ믬Ҫdzyά儊 Ѝᘐ늇Ϡͬ儺

concept Point2DConcept<typename T> : PointNDConcept<T> {    
    where num_dimensions == 2;
    where SameType<axis<0>::type, axis<1>::type>;

    typename value_type = axis<0>::type;

    const value_type& operator[](const T&, size_t i);
          value_type& operator[](      T&, size_t i);

    value_type x,y;
};

Ϡ阸ń/b>

  • PointNDConcept<T>
  • Point2DConcept<T>

ģЍ:

GIL ̡驁ˠPoint2DConcept儒븶ģЍpoint2<T>,Ƥ֐T ʇ׸᪵ĀЍ. .


4. ͨ值/a>

ͨ倖芾ѕɫש쾵ćﶈ(=ȧ, RGBϱ˘֐儺쉫ͨ倩. 夐͵č貲♗簼(뱈ᬱȽϺ͉薃ͨ倵Ė寵ͨ倓ꍗֵ.GIL傻貲ʇҔς腄ģЍ:

concept ChannelConcept<typename T> : EqualityComparable<T> {
    typename value_type      = T;        // ʹӃ channel_traits<T>::value_type 烎ʼ/span>
       where ChannelValueConcept<value_type>;
    typename reference       = T&;       // ʹӃ channel_traits<T>::reference 烎ʼ/span>
    typename pointer         = T*;       // ʹӃ channel_traits<T>::pointer 烎ʼ/span>
    typename const_reference = const T&; // ʹӃ channel_traits<T>::const_reference 烎ʼ/span>
    typename const_pointer   = const T*; // ʹӃ channel_traits<T>::const_pointer 烎ʼ/span>
    static const bool is_mutable;        // ʹӃ channel_traits<T>::is_mutable 烎ʼ/span>

    static T min_value();                // ʹӃ channel_traits<T>::min_value 烎ʼ/span>
    static T max_value();                // ʹӃ channel_traits<T>::min_value 烎ʼ/span>
};

concept MutableChannelConcept<ChannelConcept T> : Swappable<T>, Assignable<T> {};

concept ChannelValueConcept<ChannelConcept T> : Regular<T> {}; 

GILԊʹӃĚĕ됍ꍸᵣЍ׷Ϊͨ倀Ѝ. Ҳ䋆䏠闡ͱຍ綎琅ϢԊ鈴channel_traits 樒嬠뱵A숏儊取:

template <typename T>
struct channel_traits {
    typedef T         value_type;
    typedef T&        reference;
    typedef T*        pointer;
    typedef T& const  const_reference;
    typedef T* const  const_pointer;
    
    static value_type min_value() { return std::numeric_limits<T>::min(); }
    static value_type max_value() { return std::numeric_limits<T>::max(); }
};

ȧ黍貲Џͬ監倠Ѝ,ćo˼CǼ賊儺

concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2> {
    where SameType<T1::value_type, T2::value_type>;
};

һ趍貲 Ѝԗ껻ΪƤ˻傻貲 Ѝ:

עҢ擭ChannelConceptMutableChannelConcept⢃듐Ĭȏ鷫캯ʽ. ֧㖄숏鷫캯ʽ儀Ѝ(Ҳ鳉˹ν儕Ѝᰩʇ腄ode>ChannelValueConcept億㐍. ΪK-⸶⮱ଠ〞ǒ븶16λRGBϱ˘ Ѝ,ʇ"565" λģʽ. ͨ肴㊽ꍎ뇸줒떂. ΪK֧㖕6傻貲 Ѝ, ΒCҪ䴽賀-ҽӃ . բѹ儴ꀭҽӃ ʇ腄ode>ChannelConcept億㐍, 嫊Ǻͱ儃++ ҽӃһѹ, ˼uӐĬȏ鷫캯ʽ.

עҢ彋㷨ܐ蒪攍貲 Ѝʩ쓸춠儒ꇳ,=ȧҪ֧㖋㊵ԋˣ.

Ϡ阸ń/b>

  • ChannelConcept<T>
  • ChannelValueConcept<T>
  • MutableChannelConcept<T>
  • ChannelsCompatibleConcept<T1,T2>
  • ChannelConvertibleConcept<SrcChannel,DstChannel>

ģЍ:

˹ӐĚĕ됍ꍸᵣЍ漊Ǔ組ͨ倀Ѝ, GIL̡驁˒됩ջЍͨ倀Ѝ儱ꗼ樒廎p>

typedef boost::uint8_t  bits8;
typedef boost::uint16_t bits16;
typedef boost::uint32_t bits32;
typedef boost::int8_t   bits8s;
typedef boost::int16_t  bits16s;
typedef boost::int32_t  bits32s;

빓ڄڽ萍ᰵč貲 Ѝ儗ֵꍗֵ, ꍕ␩Ěͱൄί-ֵ綎璻ւ,Ҳ촍蹽std::numeric_limitsָ樵ėֵꍗֵ. Ӑʱ겎ֵ綎奔⻊ʺϵĮ GIL̡驁˼code>scoped_channel_value, ʇͨ伀ʅ䆷儒븶ģЍ, Ԋ樖Ɩ嵄綎箠ΒCԓE쀴樒堛0..1]綎焚衵㍨倀Ѝ:

struct float_zero { static float apply() { return 0.0f; } };
struct float_one  { static float apply() { return 1.0f; } };
typedef scoped_channel_value<float,float_zero,float_one> bits32f;

GIL 빌ṩKꍎ듲綎璻ւ億㐍樒廎p>

// ͨ倵Ė昭Χͨ齎umBits 樒嬠ʇChannelValueConcept億㐍
template <int NumBits> class packed_channel_value;

// ͨ倵Ė昭Χͨ齎umBits 樒嵄ҽӃ, ʇChannelConcept億㐍
template <int FirstBit, 
          int NumBits,       // 樒尼ꬍ貲ֵ儐⁐λ 
          bool Mutable>      // ȧ黑퓃޸Ĕ⎪true  
class packed_channel_reference;

// ͨ倵Ė昭Χͨ齎umBits 樒嵄ҽӃ,FirstBit ʇԋʱ⎊˼ʇChannelConcept億㐍
template <int NumBits,       // 樒尼ꬍ貲ֵ儐⁐λ 
          bool Mutable>      // ȧ黑퓃޸Ĕ⎪true 
class packed_dynamic_channel_reference;

עҢ錄⁽֖ҽӃ龜ģЍʇ⻍쵄, Ǹᰔړڍ貲ֵ綎組ƫ҆ʇͨ齇㰥⎊ҥ儻銇ͨ齔ːЊ᲎ʽ樒嵄. 麼떖ģЍ輿쬸콴䕻嚶Բ輁黮. =ȧ嚶ԊΒCͨ齍貲載듲鷫쵼了箼p> ˣ稚

ςaʇȧꎹ錟Ƚ 16λ"565" ģʽ粲ዘ Ѝ, Ȼ곉薃Ƥ׮䳖嵄ˣ稚

typedef packed_channel_reference<0,5,true> channel16_0_5_reference_t;
typedef packed_channel_reference<5,6,true> channel16_5_6_reference_t;
typedef packed_channel_reference<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();
assert(data==65535);

賒嬏ൈሽϺͿ鷫얻ʇԚ즈ݵĀЍ֮줓紖p>

packed_channel_value<5> channel_6bit = channel1;
channel_6bit = channel3;

//channel_6bit = channel2; // ᠒봭γ: Ԛ⻼賊ͨ倀Ѝ֮줸㖵.

GIL˹Ӑ傻貲ģЍ漊ǿɒԳɶԗ껻儺

channel1 = channel_traits<channel16_0_5_reference_t>::max_value();
assert(channel1 == 31);

bits16 chan16 = channel_convert<bits16>(channel1);
assert(chan16 == 65535);

ͨ倗껻ʇһ趨ɉⵄ♗笠GIL傻貲ת뻊ǒ븶ԚԴͨ倷控彄ﱪͨ倷控粲ߐԱ任. բѹ儱任Ĝ黗숷儔ڗֵꍗֵ֮줽萐ӳɤ(=ȧ,䓵int8_t迤int16_t儗껻,GIL⢃듐Ў뒆♗笒⎪ćѹ⻄ܔڗ֮줕툷ת뻬淵dz˒Բ57).

GIL˹Ӑ傻貲 Ѝ漿ɒԴӕ됍彸ᵣЍ껻,˹Ҕ˼C֧㖋㊽ԋˣ,ςaʇGIL̡駔č貲춱ൄˣ稚

// 䓔䍨倖秦뻎ꄿ᪍貲ֵ,Ԛ綎瘡ĚЏߐԓ㉤
template <typename DstChannel, typename SrcChannel>
typename channel_traits<DstChannel>::value_type channel_convert(SrcChannel src);

// 絻ؗֵ - x + min_value
template <typename Channel>
typename channel_traits<Channel>::value_type channel_invert(Channel x);

// 絻ؠa * b / max_value
template <typename Channel>
typename channel_traits<Channel>::value_type channel_multiply(Channel a, Channel b);


5. ѕɫ亍⼾ּ/a>

ѕɫ䃨ʶKש㉏ዘ儑Չ덨倵Ľ⊍ꍼﺏ, ˼ʇһ趍PL˦뺷IʵĈ݆笠༺쁋բ趿ռ䄚˹ӐҪ˘ Ѝ. }趑Չ뿕줊Ǐൈ質=ȧ,ԚϠͬ儴ΐ⏂ʇϠͬ儑Չ뼯),ćoώꋼCʇ즈ݵĮ

閣긅Į:

  • ColorSpaceConcept<ColorSpace>
  • ColorSpacesCompatibleConcept<ColorSpace1,ColorSpace2>
  • ChannelMappingConcept<Mapping>

ģЍ:

屇ൄGIL֧㖈珂儑Չ뿕줺 gray_t, rgb_t, rgba_t, ꍠcmyk_t. GIL빖糖δuu儲迤趍貲儑Չ뿕줬 devicen_t<2>, devicen_t<3>, devicen_t<4>, devicen_t<5>. 㽁˕␩᪗쵄䲼GIL빖糖 bgr_layout_t, bgra_layout_t, abgr_layout_targb_layout_t.

׷Ϊһ趀헓,ςa儴ꂫ˵÷KGILȧꎶ蒥RGBA ѕɫ集p>

struct red_t{};
struct green_t{};
struct blue_t{};
struct alpha_t{};
typedef mpl::vector4<red_t,green_t,blue_t,alpha_t> rgba_t;

ѕɫ䄚ѕɫͨ倵ĴΐⱭ÷K˼C儓䎐⮠=ȧred_t Ǡrgba_t儵ڒ븶ӯҥͨ裸ˤȻѕɫ䵄ͨ倓븶Ψһ儓䎐⬠嫊Nj샇載䦴ⴎԲ덬. ѕɫͨ倵Ĵΐ⍨齠ChannelMappingConcept ָ棇 ˼ʇһ趍PLջЍ˦뺷Iʈ݆箠ѕɫ亍λփӳɤ㒻ưʹӃ, Ҳ䋇IL샇שꏔڒ놰:

template <typename ColorSpace, 
          typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value> >
struct layout {
    typedef ColorSpace      color_space_t;
    typedef ChannelMapping  channel_mapping_t;
};

ςa儴ꂫ˵÷Kȧꎴ包 RGBA 儑Չ뿕줺

typedef layout<rgba_t> rgba_layout_t; // Ĭȏ儴ΐ⊇ 0,1,2,3...
typedef layout<rgba_t, mpl::vector4_c<int,2,1,0,3> > bgra_layout_t;
typedef layout<rgba_t, mpl::vector4_c<int,1,2,3,0> > argb_layout_t;
typedef layout<rgba_t, mpl::vector4_c<int,3,2,1,0> > abgr_layout_t;


6. ѕɫ빼/a>

ѕɫ빊ǑՉ딪˘儈݆箠ѕɫ빗㣵Ċ鈴㡾ʇ׷Ϊϱ˘儊取, բѹѕɫ빵ĔꋘǑՉ덨倵Ė寵嫊ǑՉ뻹儸ńԊ鈴ԚƤ˻儳ᾰ֐. =ȧ, plannar ϱ˘儑Չ덨儱늇l䦴ⵄ, ˼儒퓃ʇͨ齴ꀭ ʵϖ靚 ƤԪ˘ Ѝʇͨ倒퓃. planarϱ˘弴ꆷҲʇʹӃѕɫ빊取靚 ƤԪ˘ Ѝʇͨ倵촺Ʒ.

ѕɫ빱ؐ낺ףςP腄Ҫdz:

concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T> {
    // GIL ⼾֠(ѕɫ亍Ԫ˘ŅP)
    typename layout_t;
        
    //  K-趔ꋘ儀Ѝ
    template <int K> struct kth_element_type;
        where Metafunction<kth_element_type>;
    
    // at_c儽ṻ Ѝ
    template <int K> struct kth_element_const_reference_type;
        where Metafunction<kth_element_const_reference_type>;        
    
    template <int K> kth_element_const_reference_type<T,K>::type at_c(T);
    
    template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 
        T::T(T2);
    template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 
        bool operator==(const T&, const T2&);
    template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 
        bool operator!=(const T&, const T2&);

};

concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> {
    template <int K> struct kth_element_reference_type;
        where Metafunction<kth_element_reference_type>;

    template <int K> kth_element_reference_type<T,K>::type at_c(T);
    
    template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> } 
        T& operator=(T&, const T2&);
};

concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T> {
};

concept HomogeneousColorBaseConcept<ColorBaseConcept CB> {
    // 攓ڋ銬儔ڇ輤[0 ... size<C1>::value-1)֐儋:
    // oף SameType<kth_element_type<K>::type, kth_element_type<K+1>::type>;    
    kth_element_const_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n) const;
};

concept MutableHomogeneousColorBaseConcept<MutableColorBaseConcept CB> : HomogeneousColorBaseConcept<CB> {
    kth_element_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n);
};

concept HomogeneousColorBaseValueConcept<typename T> : MutableHomogeneousColorBaseConcept<T>, Regular<T> {
};

concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2> {
    where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
    // ͬѹ, 攓ڔڇ輤[0 ... size<C1>::value)儋銬K:
    //     ʇ껻儠Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
    //     Ҳʇ껻儠Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
};

ѕɫ빱ؐ뾟ӐϠ陣đՉ벼Ѝ(ༀ莚ɫ亍ѕɫͨ倵Ĵΐ⩮ Ӑ}֖罷趔ѕɫ빵ĒꋘЋ璽烎ʺ һ֖ʇͨ齶Դ洢λփɏ載˷ҽֵ,һ֖ʇͨ齒ꋘԚѕɫ䉏儓˷ҽֵ. =ȧ, RGB ѕɫ䵄儴ΐ⊇{red_t, green_t, blue_t}. 渶ԓڠBGR 儑Չ벼 Ƥί-Ņ儵ڒ븶˷ҽֵŒɫ, 渵ڒ븶ӯҥҪ˘ʇꬉ뮠腄code>ColorBaseConcept 億㐍ᘐ댡騶 at_c<K>(ColorBase) ,ԊകՎ䎐ⷃΊҪ˘. GIL 빌ṩKꯊcode>semantic_at_c<K>(ColorBase) (Ҕ곔ك芶) 攠ColorBaseConcept 億㐍ٗ茆廘Ϡ陣ēҪ˘.

ȧ黁햖ѕɫ빵đՉ뿕줊Ǐൈ靚 ⢇҆䒪˘ Ѝʇԗ껻靚ćo˼CǼ賊儮

Models:

GIL ̡驁ˍ얊ѕɫ빸ń샇儒ꋘ Ѝ漊Ǐͬ儩億㐍.

namespace detail {
    template <typename Element, typename Layout, int K> struct homogeneous_color_base;
}

GILϱ˘, planarϱ˘ҽӃꍰlanerϱ˘弴ꆷ漊NJ鈴ѕɫ빸ńϖ儮 ColorBaseConcept 俊퍢һ趄㐍ʇpacked_pixel - ˼粲ዘͨ伀ǎ듲, ⎼렼a class="el" href="gildesignguide.html#PixelSectionDG">7. ϱ˘ .

ˣ稚

GIL Ϊѕɫ빌ṩKҔς儺ꍔ꺯ʽ:

// Ҕ mpl::int_Ўʽ絻ؑՉ뻹Ԫ˘越Ԫꯊspan>
template <class ColorBase> struct size;

// ꯊemantic_at_c<K>(color_base)儷廘 Ѝ
template <class ColorBase, int K> struct kth_semantic_element_reference_type;
template <class ColorBase, int K> struct kth_semantic_element_const_reference_type;

// 僵픪˘瀏K 趓˷ҽ儒퓃.
template <class ColorBase, int K> 
typename kth_semantic_element_reference_type<ColorBase,K>::type       semantic_at_c(ColorBase& p) 
template <class ColorBase, int K> 
typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p) 

// 僵t_color<Color>(color_base)絻ؖ嵄 Ѝ
template <typename Color, typename ColorBase> struct color_reference_t;
template <typename Color, typename ColorBase> struct color_const_reference_t;

// 絻ؖ趨ѕɫ儔ꋘ˷ҽ
template <typename ColorBase, typename Color> 
typename color_reference_t<Color,ColorBase>::type get_color(ColorBase& cb, Color=Color());
template <typename ColorBase, typename Color> 
typename color_const_reference_t<Color,ColorBase>::type get_color(const ColorBase& cb, Color=Color());

// ѕɫ빵Ĕꋘ Ѝ,ֻΪͬ֊儑Չ뻹樒彎span>
template <typename ColorBase> struct element_type;
template <typename ColorBase> struct element_reference_type;
template <typename ColorBase> struct element_const_reference_type;

GIL 빌ṩK♗瑕ɫ빵ď,עҢ˼C漊Ǔ㉶ԅŁ

// 攓據᪗쿢儠std::equal, std::copy, std::fill, std::generate
template <typename CB1,typename CB2>   bool static_equal(const CB1& p1, const CB2& p2);
template <typename Src,typename Dst>   void static_copy(const Src& src, Dst& dst);
template <typename CB, typename Op>    void static_generate(CB& dst,Op op);

// 攓據᪗쿢儠std::transform
template <typename CB ,             typename Dst,typename Op> Op static_transform(      CB&,Dst&,Op); 
template <typename CB ,             typename Dst,typename Op> Op static_transform(const CB&,Dst&,Op); 
template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform(      CB1&,      CB2&,Dst&,Op); 
template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform(const CB1&,      CB2&,Dst&,Op); 
template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform(      CB1&,const CB2&,Dst&,Op); 
template <typename CB1,typename CB2,typename Dst,typename Op> Op static_transform(const CB1&,const CB2&,Dst&,Op); 

// 攓據᪗쿢儠std::for_each
template <typename CB1,                          typename Op> Op static_for_each(      CB1&,Op); 
template <typename CB1,                          typename Op> Op static_for_each(const CB1&,Op); 
template <typename CB1,typename CB2,             typename Op> Op static_for_each(      CB1&,      CB2&,Op); 
template <typename CB1,typename CB2,             typename Op> Op static_for_each(      CB1&,const CB2&,Op); 
template <typename CB1,typename CB2,             typename Op> Op static_for_each(const CB1&,      CB2&,Op); 
template <typename CB1,typename CB2,             typename Op> Op static_for_each(const CB1&,const CB2&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(      CB1&,      CB2&,      CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(      CB1&,      CB2&,const CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(      CB1&,const CB2&,      CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(      CB1&,const CB2&,const CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&,      CB2&,      CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&,      CB2&,const CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&,const CB2&,      CB3&,Op); 
template <typename CB1,typename CB2,typename CB3,typename Op> Op static_for_each(const CB1&,const CB2&,const CB3&,Op); 

// ςPꯊ햻ʇʊӃӚͬ֊儑Չ뻹:
// 攓據᪗쿢儠std::fill
template <typename HCB, typename Element> void static_fill(HCB& p, const Element& v);

// 攓據᪗쿢儠std::min_element ꍠstd::max_element
template <typename HCB> typename element_const_reference_type<HCB>::type static_min(const HCB&);
template <typename HCB> typename element_reference_type<HCB>::type       static_min(      HCB&);
template <typename HCB> typename element_const_reference_type<HCB>::type static_max(const HCB&);
template <typename HCB> typename element_reference_type<HCB>::type       static_max(      HCB&);

բˣ稊Ƿ•ՓTL樒嵄, 嫊Nj샇⻊ǒԵ촺ƷǸ줎겎ʽ,淵ǒԑՉ뻹ꍒꋘΪ⎊m͢բˣ稍蹽᠒놷穴銵ϖ質Ҳ䋒Ԣstatic_"Ϊǰ׺). ׮곬բˣ稷IʒꋘʇҔӯҥ˷ҽ渲늇ί-˷ҽ. =ȧ, ςaʇstatic_equal: 儒븶ʵϖ

namespace detail {
template <int K> struct element_recursion {
    template <typename P1,typename P2>
    static bool static_equal(const P1& p1, const P2& p2) { 
        return element_recursion<K-1>::static_equal(p1,p2) &&
               semantic_at_c<K-1>(p1)==semantic_at_c<N-1>(p2); 
    }
};
template <> struct element_recursion<0> {
    template <typename P1,typename P2>
    static bool static_equal(const P1&, const P2&) { return true; }
};
}

template <typename P1,typename P2>
bool static_equal(const P1& p1, const P2& p2) {
    gil_function_requires<ColorSpacesCompatibleConcept<P1::layout_t::color_space_t,P2::layout_t::color_space_t> >(); 
    return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); 
}    

Ԛ}趏ዘɏ巔oٗ緻 operator== 儊Ẳ롊鈴բ趨㷨. ʹӃӯҥ˷ҽ롕툷儱ȽϒGBꍂGRϱ˘. עҢ彈繻ˣ稓법ߒԉϵđՉ뻹⎊ǃ䋼Cᘐ늴ӚϠͬ儑Չ뿕줮


7. ϱ˘

һ趏ዘǔڍ쏱ָ樵㵄ѕɫͨ值ﺏ. 䓸ń˵,ҲΪϱ˘儔ꋘ ЍʇChannelConcept億㐍,˹Ҕϱ˘ᘈ늇ѕɫ빵ćﻯ Ѝ. ϱ˘儋銬ʴ漼̳ԑՉ뻹: ȧ黋銬傻貲 Ѝһւ,ćoϱ˘Ǎ얊儻籔⊇Ҭ֊儮 ϱ˘傻貲ֵԍ蹽ӯҥֵꍎֵ˷ҽ,법ߍ蹽ѕɫ˷ҽ. ˹Ӑѕɫ빵ċ㷨漊ʓOڏዘ. ȧ黏ዘ儑Չ뿕줏ͬ,⢇ґՉ덨倓ɏ즈ݬćo}趏ዘ ЍҲỈώꊇ즈ݵĮ עҢ彳, Ě䦗閯Ҕ찒퓃/ֵ刌ص八ồ⺶”儮 =ȧ,һ躉λplanar儒GBҽӃꍒ븶㣁﩮terleaved儂GRϱ˘ֵԚЍᰉϊǼ賊儮 㶠ʽ儳ɶԏዘ컲ٗ穌opy鷫쬸㖵,Ϡ刐ԵȵȩֻԚ즈ݵĀЍ֮줓箼p> ϱ˘ (빓І䋻빓ڏዘ儇IL鷫쬀툧弴ꆷ,樎놷,ʓͼꍍ쏱)ᘐ댡驏๘儔꺯ʽ烎ʆ䑕ɫ䬍貲ӳɤ,ͨ睬抽Ҕ찍貲(ͬ֊傻貲) Ѝ :

concept PixelBasedConcept<typename T> {
    typename color_space_type<T>;     
        where Metafunction<color_space_type<T> >;
        where ColorSpaceConcept<color_space_type<T>::type>;
    typename channel_mapping_type<T>; 
        where Metafunction<channel_mapping_type<T> >;  
        where ChannelMappingConcept<channel_mapping_type<T>::type>;
    typename is_planar<T>;
        where Metafunction<is_planar<T> >;
        where SameType<is_planar<T>::type, bool>;
};

concept HomogeneousPixelBasedConcept<PixelBasedConcept T> {
    typename channel_type<T>;         
        where Metafunction<channel_type<T> >;
        where ChannelConcept<channel_type<T>::type>;
};

ϱ˘ʇςP腄ģЍ:

concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P> {    
    where is_pixel<P>::type::value==true;
    // 攓ڃ︶ K [0..size<P>::value-1]:
    // oףChannelConcept<kth_element_type<K> >;
        
    typename value_type;       where PixelValueConcept<value_type>;
    typename reference;        where PixelConcept<reference>;
    typename const_reference;  where PixelConcept<const_reference>;
    static const bool P::is_mutable;

    template <PixelConcept P2> where { PixelConcept<P,P2> } 
        P::P(P2);
    template <PixelConcept P2> where { PixelConcept<P,P2> } 
        bool operator==(const P&, const P2&);
    template <PixelConcept P2> where { PixelConcept<P,P2> } 
        bool operator!=(const P&, const P2&);
}; 

concept MutablePixelConcept<typename P> : PixelConcept<P>, MutableColorBaseConcept<P> {
    where is_mutable==true;
};

concept HomogeneousPixelConcept<PixelConcept P> : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P> { 
    P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const { return dynamic_at_c(P,i); }
};

concept MutableHomogeneousPixelConcept<MutablePixelConcept P> : MutableHomogeneousColorBaseConcept<P> { 
    P::template element_reference_type<P>::type operator[](P p, std::size_t i) { return dynamic_at_c(p,i); }
};

concept PixelValueConcept<typename P> : PixelConcept<P>, Regular<P> {
    where SameType<value_type,P>;
};    

concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2> : ColorBasesCompatibleConcept<P1,P2> {
    // 攓ڃ︶ K [0..size<P1>::value):
    // oף ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
};

ȧ黑븶ϱ˘Ԋ鈴m͢һ趏ዘ儑Չ뿕준佼ˆᭊǃ䁽趏ዘ֮줾͊ǿɗ껻儮 ת뻊ǏԊ,焦ԳƵIJ⇒ʴӚӐ˰♗稕⊇ӉӚѕɫ亍ѕɫͨ倵Ľ싆ģĢԬ㉵ĩ. ת뻊Ǐƒ清Į億㐍:

template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
concept PixelConvertibleConcept {
    void color_convert(const SrcPixel&, DstPixel&);
};

腄code>PixelConcept ꍠPixelValueConcept ֮줵ć豰ꍍ貲ꍑՉ뻹儊ǒ둹儭ϱ˘ҽӃ龜튇澕ߵĄ㐍, 瀋듐ϱ˘ֵʇ곕ߵĄ㐍.

Ϡ阸ń/b>

  • PixelBasedConcept<P>
  • PixelConcept<Pixel>
  • MutablePixelConcept<Pixel>
  • PixelValueConcept<Pixel>
  • HomogeneousPixelConcept<Pixel>
  • MutableHomogeneousPixelConcept<Pixel>
  • HomogeneousPixelValueConcept<Pixel>
  • PixelsCompatibleConcept<Pixel1,Pixel2>
  • PixelConvertibleConcept<SrcPixel,DstPixel>

ģЍ:

׮㣓oďዘʇͬ֊ϱ˘, Ƥֵl䦴┘һư. ΪKբ趄﵄, GIL̡驁˽ṹ pixel, Ҕͨ倖庍⼾֎겎ʽ:

// ʇ HomogeneousPixelValueConcept億㐍
template <typename ChannelValue, typename Layout> struct pixel;

// GIL̡駔Ġtypedefs 
typedef pixel<bits8, rgb_layout_t> rgb8_pixel_t;
typedef pixel<bits8, bgr_layout_t> bgr8_pixel_t;

bgr8_pixel_t bgr8(255,0,0);     // Ԗὓͨ齍貲ֵ㵊컯
rgb8_pixel_t rgb8(bgr8);        // 즈ݏዘ֮줿ɒԏ໥ア乾Ԭ

rgb8 = bgr8;            // 즈ݏዘ֮줿ɒԏ໥賒庍Џൈሽϼ/span>
assert(rgb8 == bgr8);   // കՓͨ睬㖵ꍱȽϼ/span>

// }趏ዘ֮줵Ďͨ倖劇⻍쵄
assert(at_c<0>(rgb8) != at_c<0>(bgr8));
assert(dynamic_at_c(bgr8,0) != dynamic_at_c(rgb8,0));
assert(rgb8[0] != bgr8[0]); // ͬɏ (  ֻʇΪϱ˘樒偋operator[])

planar ϱ˘傻貲ֵ疲촦䢮 ˼C鲏퍬ѹ監倠Ѝ (pixel) , ˼C儒퓃 Ѝʇһ趴ꀭ , ༺언ϲy趍貲儒퓃. ςaʇ賴code>planar_pixel_reference:儊取

// ʇ HomogeneousPixel億㐍
template <typename ChannelReference, typename ColorSpace> struct planar_pixel_reference;

// 樒忉͖᤺북ҽӃ. (GILґṩKբ typedefs )
typedef planar_pixel_reference<      bits8&,rgb_t> rgb8_planar_ref_t;
typedef planar_pixel_reference<const bits8&,rgb_t> rgb8c_planar_ref_t;

עҢ彬 ꍽṹ pixel ⻒둹, planar ϱ˘ҽӃʇҔѕɫ䬶費ʇҔϱ˘⼾֎겎ʽ儮 ˼Cלʇ떂傻貲䎐⮠˼CĚ⿵Ĕꋘ䎐⃻Ӑᘒꬒ⎪˼Cʇָϲͨ倵Ē퓃.

Ӑʱ겏ዘ傻貲⻊ǗֽڶԆ뵄. =ȧ'5-5-6' ģʽ儒GBϱ˘ʇ16λ靚Ƥ red, green ꍠblue ͨ倷ֱռ0..4],[5..9] ꍠ[10..15].GIL ̡驁˕▖յďዘ豊樒廎p>

// 樒堲gb565 ϱ˘ Ѝ
typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, rgb_layout_t>::type rgb565_pixel_t;

function_requires<PixelValueConcept<rgb565_pixel_t> >();
BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2));

// 樒橋r556 ϱ˘ Ѝ
typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, bgr_layout_t>::type bgr556_pixel_t;

function_requires<PixelValueConcept<bgr556_pixel_t> >();

// rgb565 ꍠbgr556ʇ즈ݵĮ
function_requires<PixelsCompatibleConcept<rgb565_pixel_t,bgr556_pixel_t> >();

Ӑʱ견ϱ˘הɭ⻊ǗֽڶԆ뵄. =ȧ, 〞ǸኽΪRGB '2-3-2' ģʽ粲ዘ, Ƥλ㤎귮 GIL ʹӃ'λ攆맵Ą㊽ҽӃբ֖ Ѝ粲ዘ,ϱ˘弴ꆷꍍ쏱. λ攆뵄ϱ˘(빓Ѝ쏱)Ҫሽ䴕儸ኽ贔Ӻܶ஠ҲΪոኽ粲ዘʇז횶Ԇ뵄, ΒCҔC++ҽӃ Ѝ儷튽ʹӃһ趽䴕豊ϱ˘, ⢒ԃʽָի׷Ϊx_iteratorᩀ꒻ոኽ粲ዘ. 攓ڎ붔ƫ豊҃ǐ蒪һ趌؊†Ѝ儒퓃龜퀠(bit_aligned_pixel_reference)ꍒ븶̘ʢ Ѝ儵촺Ʒ (bit_aligned_pixel_iterator). λ攆븱ʽ粲ዘֵ Ѝʇpacked_pixel. ςa˵÷ȧꎊ鈴λ攆뵄ϱ˘ꍏዘ弴ꆷ:

// 䵄 BGR232 ϱ˘ҽӃ Ѝ 
typedef const bit_aligned_pixel_reference<mpl::vector3_c<unsigned,2,3,2>, bgr_layout_t, true>  bgr232_ref_t;

// 䵄 BGR232 ϱ˘弴ꆷ
typedef bit_aligned_pixel_iterator<bgr232_ref_t> bgr232_ptr_t;

// BGR232 ϱ˘ֵ Ѝ. ˼ʇһ趲趗ֽڠpacked_pixel . (׮곒뎻uӐʹӃ)
typedef std::iterator_traits<bgr232_ptr_t>::value_type bgr232_pixel_t; 
BOOST_STATIC_ASSERT((sizeof(bgr232_pixel_t)==1));

bgr232_pixel_t red(0,0,3); // = 0RRGGGBB, = 01100000 = 0x60

// 7ז횵Ļ곥Ǹǡꃈ݄ɸ趠BGR232  Ѝ粲ዘ .
unsigned char pix_buffer[7];    
std::fill(pix_buffer,pix_buffer+7,0);

// ʹӃꬉ댮㤸趏ዘ
bgr232_ptr_t pix_it(&pix_buffer[0],0);  // 䓵ڒ븶ϱ˘儰λ慠켯span>
for (int i=0; i<8; ++i) {
    *pix_it++ = red;
}
// 늇: 0x60 0x30 0x11 0x0C 0x06 0x83 0xC1

ˣ稚

숈돱˘ʇ ColorBaseConceptPixelBasedConcept 億㐍,˹ӐʊӃӚբ}躉ńˣ稒ⶼʊӃӚϱ˘:

// ȧꎷIʵڒ븶ӯҥͨ倨ꬉ멼/span>
assert(semantic_at_c<0>(rgb8) == semantic_at_c<0>(bgr8));

// ȧꎍ蹽uז烎ʺ쉫ͨ值/span>
assert(get_color<red_t>(rgb8) == get_color<red_t>(bgr8));

// m͢һ֖ʵϖ罊鱠ҫƷ⻏⻶麼떖罊/span>
assert(get_color(rgb8,red_t()) == get_color(bgr8,red_t()));

// ȧꎊ鈴ԪꯊixelBasedConcept 
BOOST_MPL_ASSERT(num_channels<rgb8_pixel_t>::value == 3);
BOOST_MPL_ASSERT((is_same<channel_type<rgb8_pixel_t>::type, bits8>));
BOOST_MPL_ASSERT((is_same<color_space_type<bgr8_pixel_t>::type, rgb_t> ));
BOOST_MPL_ASSERT((is_same<channel_mapping_type<bgr8_pixel_t>::type, mpl::vector3_c<int,2,1,0> > ));

// ϱ˘ֻʇ༺쳸捨倬ᰵľ̓끋 
BOOST_MPL_ASSERT(sizeof(rgb8_pixel_t)==3);

rgb8_planar_ref_t ref(bgr8);    // 즈ݿɱ䵄ϱ˘ Ѝ֮줊ǿɒԣopy鷫쵄 

get_color<red_t>(ref) = 10;     // 䵄ҽӃʇԸ㖵儼/span>
assert(get_color<red_t>(bgr8)==10);  // ͨ齒퓃脫䁋೶資ֵ 

// 䴽蒻躎ȟӠ儠packed ϱ˘ꍒ븶ͪȫս馵Ġunpacked ϱ˘.
rgb565_pixel_t r565;
rgb8_pixel_t rgb_full(255,255,255);

// ѵnpackedϱ˘儋銬ͨ倗껻ΪpackedЎʽ, ⢇Ҷϑ԰ackedϱ˘儊햵
get_color(r565,red_t())   = channel_convert<rgb565_channel0_t>(get_color(rgb_full,red_t()));
get_color(r565,green_t()) = channel_convert<rgb565_channel1_t>(get_color(rgb_full,green_t()));
get_color(r565,blue_t())  = channel_convert<rgb565_channel2_t>(get_color(rgb_full,blue_t()));
assert(r565 == rgb565_pixel_t((uint16_t)65535));    

GIL 빌ṩK color_convert ˣ糯 ӃӚ⻍쑕ɫ亍ͨ倀Ѝ֮줵ďዘת뻺

rgb8_pixel_t red_in_rgb8(255,0,0);
cmyk16_pixel_t red_in_cmyk16;
color_convert(red_in_rgb8,red_in_cmyk16);


8. ϱ˘弴ꆷ

빱了砼/a>

ϱ˘弴ꆷʇ˦뺷Iʵ촺Ʒ, ˼儠 value_type ʇPixelValueConcept億㐍. ϱ˘弴ꆷ̡驁˔꺯ʽ烎ʆ俉ᤐԨ=ȧ, ʇ籔ʐ퐞髒ዘ監婬 僵햻恏ዘ儀Ѝ, Ҕ찋샇ʇƕͨ弴ꆷ빊ǵ촺ƷʊŤƷ:

concept PixelIteratorConcept<RandomAccessTraversalIteratorConcept Iterator> : PixelBasedConcept<Iterator> {
    where PixelValueConcept<value_type>;
    typename const_iterator_type<It>::type;         
        where PixelIteratorConcept<const_iterator_type<It>::type>;
    static const bool  iterator_is_mutable<It>::type::value;          
    static const bool  is_iterator_adaptor<It>::type::value;   // ʇ籊NJʅ䆷
};

template <typename Iterator>
concept MutablePixelIteratorConcept : PixelIteratorConcept<Iterator>, MutableRandomAccessIteratorConcept<Iterator> {};

Ϡ阸ń

  • PixelIteratorConcept<Iterator>
  • MutablePixelIteratorConcept<Iterator>

ģЍ:

GILͨ齇ڽ資ϱ˘ָի pixel<ChannelValue,Layout>*ᭊterleaved ͬ֊ϱ˘弴ꆷ億㐍; ͬѹ, ͨ齼code>packed_pixel<PixelData,ChannelRefVec,Layout>* ᭊterleaved packed ϱ˘億㐍.

GILͨ齀༣ode>planar_pixel_iteratorʵϖ planar ͬ֊ϱ˘,Ƥͨ倵촺ƷꍑՉ뿕줶슇ģॲΊςaʇʹӃunsigned char樒忉ᤵĺ͖북儰lanar Ѝ儒GB弴ꆷ:

template <typename ChannelPtr, typename ColorSpace> struct planar_pixel_iterator;

// GIL ̡駔Ġtypedefs
typedef planar_pixel_iterator<const bits8*, rgb_t> rgb8c_planar_ptr_t;
typedef planar_pixel_iterator<      bits8*, rgb_t> rgb8_planar_ptr_t;

ҲΪplanar_pixel_iterator ʇ HomogeneousColorBaseConcept億㐍 (ʇ homogeneous_color_base儗ӀЍ) , ˹Ҕ빓ڑՉ뻹儋㷨漊ʓOڋ쮋쵄ѕɫ빔ꋘ Ѝʇͨ倵촺Ʒ. =ȧ, GILʵϖplanar弴ꆷ儷튽䳌劫ς:

template <typename T>
struct inc : public std::unary_function<T,T> {
    T operator()(T x) const { return ++x; }
};

template <typename ChannelPtr, typename ColorSpace>
planar_pixel_iterator<ChannelPtr,ColorSpace>& 
planar_pixel_iterator<ChannelPtr,ColorSpace>::operator++() {
    static_transform(*this,*this,inc<ChannelPtr>());
    return *this;
}

ҲΪꯊode>static_transformʇ᠒놚穴鬋鍆rgb8_planar_ptr_t 儀ۼӲٗ羍ʇ3䎖蕫쓮 GIL빍蹽 Ѝ bit_aligned_pixel_iterator ֧㖎붔ƫϱ˘弴ꮠԚĚ⿋쎬뤗ŵᇰ儗ֽں͎놫҆ .

ϱ˘ʊŤƷ

弴ꆷʊŤƷǏዘ儰칼Ʒ. ϱ˘ʊŤƷ儼code>is_iterator_adaptor ᘶ莪զ, ˼Ҳᘐ댡駁ɔắʽ烎ʆ丰䡵촺Ʒ, ЍҔ찰㶨彆䋻弴ꆷ儔꺯ʽ:

concept IteratorAdaptorConcept<RandomAccessTraversalIteratorConcept Iterator> {
    where SameType<is_iterator_adaptor<Iterator>::type, mpl::true_>;

    typename iterator_adaptor_get_base<Iterator>;
        where Metafunction<iterator_adaptor_get_base<Iterator> >;
        where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
    
    typename another_iterator; 
    typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
        where boost_concepts::ForwardTraversalConcept<another_iterator>;
        where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;

    const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
};

template <boost_concepts::Mutable_ForwardIteratorConcept Iterator>
concept MutableIteratorAdaptorConcept : IteratorAdaptorConcept<Iterator> {};

Ϡ阸ń

  • IteratorAdaptorConcept<Iterator>
  • MutableIteratorAdaptorConcept<Iterator>

ģЍ:

GIL ̡驁˼踶 IteratorAdaptorConcept億㐍:

  • memory_based_step_iterator<Iterator>: 脫丰䡵촺Ʒ⽳䵄弴ꆷ (⎼렼a class="el" href="gildesignguide.html#StepIteratorDG">Step Iterator)
  • dereference_iterator_adaptor<Iterator,Fn>: ͨ齒딪ꯊode>Fn 퓃儊ʅ䆷. ԓA䗶Yʱ儑Չ뗪뻬 Ҳ×篩aɏ덬儑Չ뿕줺͍貲ɮ戟ć㲣ͼϱ"ʓͼ". 輶ൄЅϢ⎼렼a class="el" href="gildesignguide.html#ImageViewFrowImageViewDG">Creating Image Views from Other Image Views . һԪꯊcode>Fn ᘐ늇 PixelDereferenceAdaptorConcept億㐍 (컏c.

ϱ˘퓃ʊŤƷ

ϱ˘퓃ʊŤƷʇһ趒딪ꯊɒԶԒ븶ϱ˘弴ꆷ퓃. ˼儲Ί퀠ЍʇȎҢ質八PixelConcept),嫊dž佡黀Ѝᘐ늇PixelConcept

template <boost::UnaryFunctionConcept D>
concept PixelDereferenceAdaptorConcept : DefaultConstructibleConcept<D>, CopyConstructibleConcept<D>, AssignableConcept<D>  {
    typename const_t;         where PixelDereferenceAdaptorConcept<const_t>;
    typename value_type;      where PixelValueConcept<value_type>;
    typename reference;       where PixelConcept<remove_reference<reference>::type>;  // may be mutable
    typename const_reference;   // ᘶ費ʇ䵄
    static const bool D::is_mutable;

    where Convertible<value_type, result_type>;
};

ģЍ:

GIL ̡驁˼踶 PixelDereferenceAdaptorConceptģЍ

  • color_convert_deref_fn: ִѕɫ᤻뼯li>
  • detail::nth_channel_deref_fn: 絻ؖ趨ϱ˘嚮趍貲攓淨뒶ȏዘ
  • deref_compose: 攸ńode>PixelDereferenceAdaptorConcept俊ģЍϳɮ ꍼcode>std::unary_composeϠˆ,ֻʇ빐蒪Զ쓸ńcode>PixelDereferenceAdaptorConcept˹Ҫ儼踶 Ѝ樒封/li>

GIL ͨ噤ⒽӃʊŤƷʵϖͼϱʓͼ儑Չ뱤뻬 법ߵo폱˘嚮趍貲儻ҶȖ寵ͨ齈Βⵄꯊ뻬 퓃ʊŤƷʵԓA䊵ϖĢͼϱʓͼ, =ȧ Mandelbrot 쯮 dereference_iterator_adaptor<Iterator,Fn> ʇһ趏ዘ弴ꆷ༹솷,ͨ齺Fn Џዘ儽ⒽӃ.

Step 弴ꆷ

Ӑʱ겎҃Ǐ㍻Ҕ奎벽㤶費ʇϱ˘ָ樵IJᩀꏱ˘弴ꆷ,ςa儊˵÷բ躉ńӐӃ:
  • RGB interleavedͼϱ儺쉫ͨ倵ĵ契伀Ӎ켯li>
  • 䓗㵽Ӓ仲굄ʓͼ (step = -fundamental_step)
  • yN趏ዘ儗ӊӍ쨳tep = N*fundamental_step)
  • 乖᷽ϲᩀ굄ʓͼ (step = y儗ֽڊ/li>
  • ɏa儈Β◩ꏠ(⽳䊇Ϡ㋵ĩ

Step 弴ꆷʇǰϲ弴ꆷ, Ԋ髒Z弴ꆷ֮줵IJ :

concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
    template <Integral D> void Iterator::set_step(D step);
};

concept MutableStepIteratorConcept<boost_concepts::Mutable_ForwardIteratorConcept Iterator> : StepIteratorConcept<Iterator> {};

屇ൄGIL ̡駔Ġstep 弴ꆷ儠value_type ʇ PixelValueConcept億㐍. m͢, ⽳䊇빓ڄڴ浥λ質ז횻╟λ). բʇᘒ굄,=ȧ, 會Ԓ돵P粲ዘ촺儊Ẳ, һϱ˘儴㐡⻄ܱ뒻趏ዘ儴㐡ջ㽻 빱Ȉ瓔˘⻊ǗֶԆ뵄 .

ΪKĜ黑ԗֻ◖횏⇰弴ꬠ빴ᵼ了籐ʇ MemoryBasedIteratorConcept 億㐍. 빓ڄڴ淨弴ꆷӐһ趄ڔڵĴ洢奎묠λ법ߗֽڮ ˼ᘐ댡驏愜: y趴洢奎뵄λʽ(1벸), 屇ൄ⽳䬠}趵촺Ʒ֮줻銍䦴ⵥλ齉+, ָ樻銍䦴ⵥλ뵄ҽӃ. ˼빱ؐ댡騶ʹ僵촺Ʒǰ붨뮠ꯊode>memunit_advanced ꍠmemunit_advanced_ref 漓Є숏儊取,嫊dž䋻儵촺ƷԌṩ轀ӓ組঱p>

concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator> {
    typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
    std::ptrdiff_t      memunit_step(const Iterator&);
    std::ptrdiff_t      memunit_distance(const Iterator& , const Iterator&);
    void                memunit_advance(Iterator&, std::ptrdiff_t diff);
    Iterator            memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
    Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
};

ͨ齁퍢儵촺Ʒ鷫쒻足tep弴ꆷʇ꜓oĮ 輒밣儊ǖ趨һ趀Ѝ, ΒCĜ黹錟һ趶ԓ淨毌언ʼnˮƽ⽳䵄 Ѝ:

concept HasDynamicXStepTypeConcept<typename T> {
    typename dynamic_x_step_type<T>;
        where Metafunction<dynamic_x_step_type<T> >;
};

˹ӐGIL̡駔ďዘ弴ꆷ,樎놷ꍍ쏱ʓͼ億㐍漊ǖ糖 HasDynamicXStepTypeConcept.

Ϡ阸ń/b>

  • StepIteratorConcept<Iterator>
  • MutableStepIteratorConcept<Iterator>
  • MemoryBasedIteratorConcept<Iterator>
  • HasDynamicXStepTypeConcept<T>

ģЍ:

˹ӐGIL屇̡駔Ļ銍Ě䦵ĵ촺Ʒ漊ǠMemoryBasedIteratorConcept 億㐍. GIL ̡駔ĀЍ memory_based_step_iterator ʇ腄code>PixelIteratorConcept, StepIteratorConcept, ꍠMemoryBasedIteratorConcept億㐍. ˼Ҕ빴ᵼ了稱ؐ늇PixelIteratorConceptMemoryBasedIteratorConcept億㐍)ΪģॲΊ⢇Ҕʐ̬脫䲽㤮 GIL儊取༺쒻趻鴡弴ꆷꍒ븶 ptrdiff_t,ӃӚᭃ綯Ӛ䦴ⵥλ(ז횻⎻)儲ʽ. բ趲䁿Ҳԓ×縺ʽ. GIL̡驁˕6һ趺: ʹӃ빴ᵼ了纍⽳䴴븶step弴ꆷ:

template <typename I>  // ʇ MemoryBasedIteratorConceptꍠHasDynamicXStepTypeConcept億㐍
typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step);

GIL 빌ṩK position_iterator, 빓ڐ鄢ϱ˘ʽש儵촺Ʒ. ˼ʇһ足tep 弴ꆷ, 躗ْ븶ϱ˘載떃,⢇ҍ蹽為攏ዘ퓃. ˼ʇ腄code>PixelIteratorConcept ꍠStepIteratorConcept 億㐍,嫊Dz늇MemoryBasedIteratorConcept億㐍.

ϱ˘樎놷

樎놷ԊԚ2ά법߶ά䖐Ђ. 樎놷ᾖʉϊǎά靚 嫊ǒ⎪˼C⻍ꈫoף弴ꆷ儒ꇳ,ΒCҪmư¯Ԯ. =ȧ, ˼C⻄ܽ萐쓺͵ݼ岙׷,ҲΪ˼C֪倔ڄǒ븶ά戉Ͻ萐բѹ儲ٗ箠Nά弴ꆷoףҔς儸ńp>
concept RandomAccessNDLocatorConcept<Regular Loc> {    
    typename value_type;        // 樎놷¾ӎ監倠Ѝ 
    typename reference;         // ҽӃ Ѝ
    typename difference_type; where PointNDConcept<difference_type>; // operator-儀Ѝ.
    typename const_t;           // Loc儳 Ѝ
    typename cached_location_t; // 䦴⏠閻떃儀Ѝ (ΪK﬋ٵĖظ䷃Ί)
    typename point_t  = difference_type;
    
    static const size_t num_dimensions; // 樎놷載춈
    where num_dimensions = point_t::num_dimensions;
    
    // y趎춈儠difference_type ꍠ弴ꆷ Ѝ. 弴ꆷԖ늇Ԛ 
    // difference_typeɏ⻒둹. ˼C儠value_type ꍠLoc::value_typeᘐ뒻ւ
    template <size_t D> struct axis {
        typename coord_t = point_t::axis<D>::coord_t;
        typename iterator; where RandomAccessTraversalConcept<iterator>; // Dά׸᪖ᵄ弴ꆷ.
        where iterator::value_type == value_type;
    };

    // 樒庍樎놷 ˆ儀Ѝ,ֻʇԚ퓃ɏ⻍켯span>
    template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
        typename type;        where RandomAccessNDLocatorConcept<type>;
        static type make(const Loc& loc, const Deref& deref);
    };
    
    Loc& operator+=(Loc&, const difference_type&);
    Loc& operator-=(Loc&, const difference_type&);
    Loc operator+(const Loc&, const difference_type&);
    Loc operator-(const Loc&, const difference_type&);
    
    reference operator*(const Loc&);
    reference operator[](const Loc&, const difference_type&);
 
    // 䦴⏠陣Ď떃Ҕ᣿싙監ظ䷃Ί  
    cached_location_t Loc::cache_location(const difference_type&) const;
    reference operator[](const Loc&,const cached_location_t&);
    
    // Ԛ屇λփ법ߖ趨儆뒆䦷Iʵ촺Ʒ
    template <size_t D> axis<D>::iterator&       Loc::axis_iterator();
    template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
    template <size_t D> axis<D>::iterator        Loc::axis_iterator(const difference_type&) const;
};

template <typename Loc>
concept MutableRandomAccessNDLocatorConcept : RandomAccessNDLocatorConcept<Loc> {    
    where Mutable<reference>;
};

2ά樎놷빓儒ꇳ:

concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc> {
    where num_dimensions==2;
    where Point2DConcept<point_t>;
    
    typename x_iterator = axis<0>::iterator;
    typename y_iterator = axis<1>::iterator;
    typename x_coord_t  = axis<0>::coord_t;
    typename y_coord_t  = axis<1>::coord_t;
    
    // ֻʊӃӚԚY罏ⓐ毌첽㤵Ķ莻Ʒ
    //Loc::Loc(const Loc& loc, y_coord_t);

    // ֻʊӃӚԚX Y罏ⶼӐ毌첽㤵Ķ莻Ʒ
    //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);

    x_iterator&       Loc::x();
    x_iterator const& Loc::x() const;    
    y_iterator&       Loc::y();
    y_iterator const& Loc::y() const;    
    
    x_iterator Loc::x_at(const difference_type&) const;
    y_iterator Loc::y_at(const difference_type&) const;
    Loc Loc::xy_at(const difference_type&) const;
    
    // ⻍쀠Ѝ˹Ӑ罷資x/y ঱span>
    x_iterator        Loc::x_at(x_coord_t, y_coord_t) const;
    y_iterator        Loc::y_at(x_coord_t, y_coord_t) const;
    Loc               Loc::xy_at(x_coord_t, y_coord_t) const;
    reference         operator()(const Loc&, x_coord_t, y_coord_t);
    cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;

    bool      Loc::is_1d_traversable(x_coord_t width) const;
    y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
};

concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc> : MutableRandomAccessNDLocatorConcept<Loc> {};

2ά樎놷⻽濉ҔԚˮƽ罏⬒⿉ҔԚ乖᷽ϲӐһ趶攜莻⽬ բѹꉺKꍙ攓淨 HasDynamicXStepTypeConcept:

concept HasDynamicYStepTypeConcept<typename T> {
    typename dynamic_y_step_type<T>;
        where Metafunction<dynamic_y_step_type<T> >;
};

GIL̡駔ċ銬樎놷ꍍ쏱ʓͼ漊ǠHasDynamicYStepTypeConcept億㐍.

Ӑʱ겶ԒԖ趨攜莻Ʒꍍ쏱ʓͼ,Ҫ攻똺͙罏ⵄꬒ娀툧,GIL̡驁˶Ի덼ϱʓͼ儺). բѹ攜莻ƷꍊӍ챘ʇԻ뵄:

concept HasTransposedTypeConcept<typename T> {
    typename transposed_type<T>;
        where Metafunction<transposed_type<T> >;
};

GIL̡駔ċ銬攜莻ƷꍊӍ춼ʇHasTransposedTypeConcept億㐍.

GIL攜莻Ʒ♗ݵĀЍ漊ǠPixelConcept 億㐍, ⢇ҋ샇儸/yά儀Ѝʇһւ儮 ˼CʇςP腄ģЍ:

concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc> {
    where PixelValueConcept<value_type>;
    where PixelIteratorConcept<x_iterator>;
    where PixelIteratorConcept<y_iterator>;
    where x_coord_t == y_coord_t;

    typename coord_t = x_coord_t;
};

concept MutablePixelLocatorConcept<PixelLocatorConcept Loc> : MutableRandomAccess2DLocatorConcept<Loc> {};

Ϡ阸ń/b>

  • HasDynamicYStepTypeConcept<T>
  • HasTransposedTypeConcept<T>
  • RandomAccessNDLocatorConcept<Locator>
  • MutableRandomAccessNDLocatorConcept<Locator>
  • RandomAccess2DLocatorConcept<Locator>
  • MutableRandomAccess2DLocatorConcept<Locator>
  • PixelLocatorConcept<Locator>
  • MutablePixelLocatorConcept<Locator>

ģЍ:

GIL ̡驁ˠPixelLocatorConcept 俊ģЍ:빓ڄڴ淨樎놷memory_based_2d_locator ꍐ鄢樎놷 virtual_2d_locator.

memory_based_2d_locator ʇһ趻銍ϱ˘ԚĚ䦖ēOڠplanar 법ߠinterleaved ͼϱ攜莻Ʒ. ˼Ҕ StepIteratorConceptΪģॲΊ屆鈴 腄ode>MutableStepIteratorConcept儊Ẳ, 촉곉腄code>MutablePixelLocatorConcept).

template <typename StepIterator>  // ʇStepIteratorConcept, MemoryBasedIteratorConcept億㐍
class memory_based_2d_locator;

StepIterator 儲ᘐ늇빓ڴ洢奎먗ֽڻ╟λ)儃ʽ(բѹɒԏ⇰쓩. Ѝ memory_based_2d_locator ʇ StepIterator 儰칼Ʒ, ⢊鈴˼閱ӎ:,淵鈴Ƥ빴ᵼ了罰ˮƽӎ:.

ӉӚ樎놷ʹӃK빱ȝꍳtep弴ꆷ疿굄ģʽ, ˹ҔΒCԴ包ϱ˘儴洢鵃쓸䔓攜莻Ʒ. 麼묠ΒCԶԋ罏ⵄ弴ꆷᔱ, =ȧᩀꍬһ粲ዘ. ʹӃբ֖疿굄ģʽ脛ˎ҃NjĖ֑ᔱ兒Ʉܺ

  • pixel<T,C>* (ʊӃӚ interleaved ͼϱ)
  • planar_pixel_iterator<T*,C> (ʊӃӚ planar ͼϱ)
  • memory_based_step_iterator<pixel<T,C>*> (ʊӃӚ燱ꗼ⽳䵄 interleaved ͼϱ)
  • memory_based_step_iterator<planar_pixel_iterator<T*,C> > (ʊӃӚ燱ꗼ⽳䵄 planar ͼϱ)

屈묓u璲Ԍṩ˼Cה캶薆儠x-iterator. ςaeʶ儒븶=דʇһ趵촺ƷʊŤƷ,岸ⒽӃ儊ẲԽ萐ѕɫת뻮

ָ樒븶ˮƽ弴ꆷXIterator, ΒCԵo풻趔ڴ閱罏⒆毿ĵ촺Ʒ y-iterator, ҆毿IJʇmemory_based_step_iterator<XIterator> ָ樵Ļ銍䦴ⵥλ(ז횻╟λ)儃ʽ. 屈묠ȋCҲԗԓɵĶ薆 y-iterator.

բѹΒCɒԊ啥믠memory_based_2d_locator<memory_based_step_iterator<XIterator> > 僵풻趲άϱ˘樎놷,ȧςͼ˹ʾ:

step_iterator.gif

virtual_2d_locator ʇһ趍蹽為攏ዘⒽӃ攜莻Ʒ. 為絻ؖ趨X,Yλփϱ˘ֵ. Ģ樎놷ԓA䊵ϖӃ맖趨儈Βⷂꯊҥ儐鄢ͼϱʓͼ. ⎼뇉L팳̍andelbrot쯹錟儐鄢ͼϱ.

Ģ樎놷ꍻ銍Ě䦊笲樎놷漼̳Ԡpixel_2d_locator_base, բ趻造̡驁˸ńcode>PixelLocatorConceptҪ齉貰⿷ֽӿڮ ȧ黓u琨Ҫ樖Ɔ䋻儼code>PixelLocatorConcept,ćo˼C롷⏖բ趻造照㵄ӐӃ:

loc=img.xy_at(10,10);            // 䓏ዘ (x=10,y=10)慠켯span>
above=loc.cache_location(0,-1);  // 쇗቏ςZď๘λփ 
below=loc.cache_location(0, 1);
++loc.x();                       // ҆毿11,10)
loc.y()+=15;                     // ҆毿11,25)
loc-=point2<std::ptrdiff_t>(1,1);// ҆毿10,24)
*loc=(loc(0,-1)+loc(0,1))/2;     // ɨփ(10,24) 䦵ďዘΪ  (10,23)䦺͠(10,25)䦵ľ閵 (ֻʊӃӚ뒶ȼ揱˘)
*loc=(loc[above]+loc[below])/2;  // ͬɏ,ֻʇӉӚʹӃK뺴恚Ď떃,˹Ҕ輿젼/span>

᪗쵄GIL樎놷漊ǿ싙儇ၿ춵Ķԏ㮠=ȧ첵嵄interleavedͼϱ攜莻Ʒ,ֻʇ༺쒻趖菲ϱ˘ưʼλփ儂㖸իꍒ븶ʽ㐡儕늽, ל鯨趗ֽڮ ++loc.x() ל鮦늇˒봎£ָի儀ۼӲٗ稻╟ʇ攓ڰlanarͼϱ載䎀ۼӲٗ穮 ҲΪҪӷ躍㋷蔋ˣ,˹Ҕ2ά儆뒆♗珠攽ς=ȧ齂ˆ羍Ҫ烎ʃ︶ϱ˘粲ͬZԚբ֖ǩﶏŽ҃ǿɒԊ鈴 cache_location뺴揠攎떃. Ԛɏa儊啥֐, 첵婮terleavedͼϱʹӃ儴ꂫ loc[above],Ǿ͊ǽ萐ʽש˷ҽ♗箼h2> 2άͼϱ弴ꆷ Ӑ儊ẲΒCҪҔλփ態ⵄ罊ͬѹ粲ዘᩀ겙׷, Ԛբ֖ǩﶏ°ዘʓΪһά儊헩롷dz㵄ӐӃ. GIL儀༣ode>iterator_from_2dʇһ趨浟烎ʵ촺Ʒ, ˼Ҕһ֖הȻ靚䦴ⓑꃵķ튽䓗㵽Ӓ,䓉ϵ폂ᩀꏱ˘. ˼Ҕ樎놷,ͼϱ兒ꍵᇰ儘λփΪ⎊6⅓㹻儐ŏ⾶樺ΊỘת,腒ꈧς:

template <typename Locator>  // ʇ PixelLocatorConcept億㐍
class iterator_from_2d {
public:
    iterator_from_2d(const Locator& loc, int x, int width);
    
    iterator_from_2d& operator++(); // if (++_x<_width) ++_p.x(); else _p+=point_t(-_width,1);

    ...
private:
    int _x, _width;
    Locator _p;
};

ͨ齼code>iterator_from_2d 攍쏱ϱ˘촺,Ҫል蹽y弴ꬲ⇒Ԛy֐ʹӃx-iterator弴굄˙戒ꂽ. բʇҲΪy趵촺⽖蒪ሽϬһ䎊ǶԽኸ̵쾵ąϬmһ䎊ǔڠiterator_from_2d::operator++ Ě⿼첩ʇ籵β. 攓ړ鿬˙儲ٗ笀툧ϱ˘廣opy, 嚶쬲黶Զ쓱5%儐Ԅ܋ʧ(բʇԚIntelƽ̨ɏ儲ⁿ멮 GIL ֘ԘKһSTLˣ糯 =ȧ std::copystd::fill, 展␩ˣ稒Ը-iteratorsΪ빴ᬠ巔ucode>iterator_from_2d-s遠儊Ẳ,ȧ黍쏱uӐ̮㤨=ȧ iterator_from_2d::is_1d_traversable()絻شrue),ćoᖱ퓊鈴x-iterators첻ﱩ:♗箼p>


9. ͼϱʓͼ

ͼϱʓͼʇSTLǸ줸ń紵מּߓึά戮 ꍇ輤(核浼了穩ˆ, ͼϱʓͼʇdz⣵Ĭ ˼⢲듵ӐʽҲ⻻ᓰϬʽ儳̘. =ȧ, һ足傻쏱ʓͼ⢲넜脫䴳,嫊ǔʐ퐞髒ዘ. 攓ڏዘ⻿ɱ䵄♗笊鈴ʽʇ̘傻쏱ʽҲㆎꮯn-mutableͼϱʓͼ). N-ά傻쏱ʓͼoףςa儸ńdz:

concept RandomAccessNDImageViewConcept<Regular View> {
    typename value_type;      // 攓ڻ銍ϱ˘儊Ӎ쬾͊Ǐዘ儀Ѝ
    typename reference;       // ҽӃ Ѝ
    typename difference_type; // operator-(iterator,iterator) (1-ά!)儀Ѝ
    typename const_t;  where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
    typename point_t;  where PointNDConcept<point_t>; // N-ά壼/span>
    typename locator;  where RandomAccessNDLocatorConcept<locator>; // N-ά樎놷.
    typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-ά弴ꆷ
    typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>; 
    typename size_type;       // size()儀Ѝ

    // 攓據RandomAccessNDLocatorConcept::axis
    template <size_t D> struct axis {
        typename coord_t = point_t::axis<D>::coord_t;
        typename iterator; where RandomAccessTraversalConcept<iterator>;   // 嚄趗豪֡儵촺Ʒ.
        where SameType<coord_t, iterator::difference_type>;
        where SameType<iterator::value_type,value_type>;
    };

    // 㽁˔ڽⒽӃɏ巔Aeref(ҫ՟ע:⻊ǖὓ퓃),樒庍ʓͼһւ儊Ӎ쀠Ѝ
    template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
        typename type;        where RandomAccessNDImageViewConcept<type>;
        static type make(const View& v, const Deref& deref);
    };

    static const size_t num_dimensions = point_t::num_dimensions;
    
    // 䓶莻Ʒꍗ㉏퇒Լά戴包ʓͼ
    View::View(const locator&, const point_type&);
    
    size_type        View::size()       const; // Ԫ˘儗ܸ抽 
    reference        operator[](View, const difference_type&) const; // 1-άҽӃ
    iterator         View::begin()      const;
    iterator         View::end()        const;
    reverse_iterator View::rbegin()     const;
    reverse_iterator View::rend()       const;
    iterator         View::at(const point_t&);
    point_t          View::dimensions() const; // y趎춈儔ꋘʽ
    bool             View::is_1d_traversable() const;   // ʇ籤糖һάᩀ꿼/span>

    // 僵햸樵Ď춈ꍖ趨壯ĵ촺Ʒ
    template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;

    reference operator()(View,const point_t&) const;
};

concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View> {
    where Mutable<reference>;
};

2ά傻쏱ʓͼ빓儒ꇳ:

concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
    where num_dimensions==2;

    typename x_iterator = axis<0>::iterator;
    typename y_iterator = axis<1>::iterator;
    typename x_coord_t  = axis<0>::coord_t;
    typename y_coord_t  = axis<1>::coord_t;
    typename xy_locator = locator;
    
    x_coord_t View::width()  const;
    y_coord_t View::height() const;
    
    // X-罏Ⱪ:
    x_iterator View::x_at(const point_t&) const;
    x_iterator View::row_begin(y_coord_t) const;
    x_iterator View::row_end  (y_coord_t) const;

    // Y-罏Ⱪ:
    y_iterator View::y_at(const point_t&) const;
    y_iterator View::col_begin(x_coord_t) const;
    y_iterator View::col_end  (x_coord_t) const;
       
    // 2άᩀ꼯span>
    xy_locator View::xy_at(const point_t&) const;

    //  Ҕpoint_tΪ⎊˹Ӑ罷資(x,y)঱ϖ    
    View::View(x_coord_t,y_coord_t,const locator&);
    iterator View::at(x_coord_t,y_coord_t) const;
    reference operator()(View,x_coord_t,y_coord_t) const;
    xy_locator View::xy_at(x_coord_t,y_coord_t) const;
    x_iterator View::x_at(x_coord_t,y_coord_t) const;
    y_iterator View::y_at(x_coord_t,y_coord_t) const;
};

concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
  : MutableRandomAccessNDImageViewConcept<View> {};

夐͵ćILͼϱʓͼoף PixelValueConcept , ⢇ғ儒ꇳ:

concept ImageViewConcept<RandomAccess2DImageViewConcept View> {
    where PixelValueConcept<value_type>;
    where PixelIteratorConcept<x_iterator>;        
    where PixelIteratorConcept<y_iterator>;
    where x_coord_t == y_coord_t;
    
    typename coord_t = x_coord_t;

    std::size_t View::num_channels() const;
};


concept MutableImageViewConcept<ImageViewConcept View> : MutableRandomAccess2DImageViewConcept<View> {};

ȧ黁ͼϱʓͼά戲ͬ,⢇ҏዘ Ѝʇ즈ݵĬćo˼C눏Ϊʇ즈ݵĺ

concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2> {
    where PixelsCompatibleConcept<V1::value_type, V2::value_type>;
    where V1::num_dimensions == V2::num_dimensions;
};

즈ݵĊӍ챘Џͬ載춈(=ȧ, Ϡͬ儸߶ȺͿ).ꜶҔ核抓ͼΪ⎊ˣ稒ꇳ˼Cʇ즈ݵĠ.

Ϡ陣ĸń/b>

  • RandomAccessNDImageViewConcept<View>
  • MutableRandomAccessNDImageViewConcept<View>
  • RandomAccess2DImageViewConcept<View>
  • MutableRandomAccess2DImageViewConcept<View>
  • ImageViewConcept<View>
  • MutableImageViewConcept<View>
  • ViewsCompatibleConcept<View1,View2>

ģЍ:

GIL ̡駔ļcode>ImageViewConcept 億㐍ʇ image_view, ˼ҔPixelLocatorConceptΪģॲΊ(ȧ黑Լcode>MutablePixelLocatorConceptΪģॲΊćoǠMutableImageViewConcept). ȧς:

template <typename Locator>  // ʇ腄ixelLocatorConcept億㐍 (ҲԊǠMutablePixelLocatorConcept)
class image_view {
public:
    typedef Locator xy_locator;
    typedef iterator_from_2d<Locator> iterator;
    ...
private:
    xy_locator _pixels;     // Ԛͼϱ׳ɏ퇵IJάϱ˘樎놷
    point_t    _dimensions; // 蟶ȺͿ
};

ͼϱʓͼʇǡ춵Ķԏ㬠һ足㹦儠interleaved ʓͼ夐͊NJDZ6趗ֽڵĴ㐡 : }趲튾㤶ȺͿ儕늽(༺씚ά戟㖐),һ趲튾ϠZ儗ֽڴ㐡儕늽(༺씚樎놷֐),Ҕ찒븶ᭊϱϱ˘ʽ銗嘖組ָի.

ˣ稚

䓂㏱˘ʽ包ʓͼ

䓈κΖ糖儑Չ뿕줬λɮ戩ͨ笨ΐ⒔찰lanar,interleaved鴟£ʽ쿉Ҕ鷫챪׼儊Ӎ쮠Interleaved ʓͼʹӃ interleaved_view鷫쬠Ҫ̡驍쏱載춈,y儗ֽڊָϲ麼븶ϱ˘監蕫:

template <typename Iterator> // ϱ˘弴ꆷ監蕫 (=ȧ rgb8_ptr_t 법ߠrgb8c_ptr_t)
image_view<...> interleaved_view(ptrdiff_t width, ptrdiff_t height, Iterator pixels, ptrdiff_t rowsize)

Planar ʓͼʹӃy趑Չ뿕줶蒥, ςaʇһ趒GB儐Ίp>

template <typename IC>  // Models channel iterator (like bits8* or const bits8*)
image_view<...> planar_rgb_view(ptrdiff_t width, ptrdiff_t height,
                                 IC r, IC g, IC b, ptrdiff_t rowsize);

עҢ彌ṩ粲ዘ/ͨ倵촺ƷԊdz(⻱䩵촺Ʒ,Ԛբ֖ǩﶏ1錟儊Ӎ쒲ʇ㣁免뱤)ʓͼ .

䓆䋻儊Ӎ촴쏱ʓͼ

脫䍼ϱʓͼʽ鈴億㐩罊ɒԹ錟һ趐μč쏱ʓͼ. Ђ儊Ӎ쵄 Ѝʇ䓔䊓ͼ儀Ѝќɺ㶀䵄, GIL̡驁˒ԏμĔ꺯ʽ4僵표ɺ儀Ѝ:

// һʓͼ Ѝ
template <typename View> 
struct dynamic_xy_step_type : public dynamic_y_step_type<typename dynamic_x_step_type<View>::type> {};

template <typename View> 
struct dynamic_xy_step_transposed_type : public dynamic_xy_step_type<typename transposed_type<View>::type> {};

// 舉Չ뺍λɮ껻
template <typename SrcView, // ImageViewConcept億㐍
          typename DstP,    // PixelConcept億㐍
          typename ColorConverter=gil::default_color_converter>    
struct color_converted_view_type {
    typedef ... type;     // 튊Ť傻쏱ʓͼ
    };

// N趍貲儵契伀Ӎ켯span>template <typename SrcView>
struct nth_channel_view_type {
    typedef ... type;
};

GIL ̡驁ˈ珂儊Ӎ엪뻺

// ɏς,׳Ӓꍋ돲仲굄ʓͼ
template <typename View> typename dynamic_y_step_type<View>::type             flipped_up_down_view(const View& src);
template <typename View> typename dynamic_x_step_type<View>::type             flipped_left_right_view(const View& src);
template <typename View> typename dynamic_xy_step_transposed_type<View>::type transposed_view(const View& src);

// ת
template <typename View> typename dynamic_xy_step_type<View>::type            rotated180_view(const View& src);
template <typename View> typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(const View& src);
template <typename View> typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(const View& src);

// η控Ě⿵ėӊӍ켯span>
template <typename View> View                                                 subimage_view(const View& src, 
             const View::point_t& top_left, const View::point_t& dimensions);

// ԚXY}趷폲줸䵄ʓͼ
template <typename View> typename dynamic_xy_step_type<View>::type            subsampled_view(const View& src, 
             const View::point_t& step);

template <typename View, typename P> 
color_converted_view_type<View,P>::type                                       color_converted_view(const View& src);
template <typename View, typename P, typename CCV> // 樖ƵđՉ뱤뻼/span>
color_converted_view_type<View,P,CCV>::type                                   color_converted_view(const View& src);

template <typename View> 
nth_channel_view_type<View>::view_t                                           nth_channel_view(const View& view, int n);

㶠ʽʓͼ䴽資ˣ稶슇ֱ׵Ĭςaʇһ越Ӎ췭תʵϖ儀헓. ɏς仲꼣ode>䴽資ʓͼ儵ڒ븶ϱ˘ʇԴʓͼ׮骨粲ዘ,⢇Ҕڹ罏ⵄ⽳䊇Ϡ紵Į

template <typename View>
typename dynamic_y_step_type<View>::type flipped_up_down_view(const View& src) { 
    gil_function_requires<ImageViewConcept<View> >();
    typedef typename dynamic_y_step_type<View>::type RView;
    return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
}

巔u gil_function_requires 롈籣 (Ԛ᠒놚)ģॲΊ튇  ImageViewConcept億㐍. ʹӃբ趺롱Ƚψݒ׸ꗙ᠒봭γ,⢇Ҳ뻡Զ쓴ꂫ̥뽺͔ːЊᵄ摒ꮠΒCʹӃKꯊ boost::concept_check , ⢇Ұ칼Ϊ gil_function_requires, 빉薃Kһ趿깘ѡϮ BOOST_GIL_USE_CONCEPT_CHECK ,Ĭȏʇ阱յĬ բַҪʇҲΪһ婿ꆴբ趑Ꮾ롏Ԗ資Զ쓱ҫʱ줮 Ԛᾎĵ喐, ΪK첽଎҃ǻጸ齕⸶ꯊ⩮

ͼϱʓͼ֮줿ɒԗԓɗ麇(⎼렼a class="el" href="gildesignguide.html#MetafunctionsDG">12. ʹӃԪꯊTypedefs ֐儀Ѝ樒封code>rgb16_image_t ꍠgray16_step_view_t):

rgb16_image_t img(100,100);    // һ趠RGB interleaved 傻쏱

// img儂̉덨倨ͨ個璽ꅱ)ɺ㉵ĻҶȼ抓ͼ
gray16_step_view_t green=nth_channel_view(view(img),1);

// 50x50 䳐ᵄʓͼ,ɏς仲겢ǒԚXY罏ⶼʇy賢됐ȡʽ/span>
gray16_step_view_t ud_fud=flipped_up_down_view(subsampled_view(green,2,2));

ȧǰ˹ʶ,ͼϱʓͼ儹錟ʇ﬋ٵĬ㣁줵Ĭʇ攍쏱ʽĒ븶dz⣓㏱. ɏa儴ꂫ⻻ᖴϱ˘ʽĿ, ʽǍ쏱䴽資ʱ겷օ䵄.

ͼϱʓͼ儓TLЎʽ儋㷨

ͨ齷 begin() ꍠend() ,ͼϱʓͼ̡驁˶ԏዘ儱ά弴ꆷ, բʹ僿ɒԓ擃STLˣ種 嫊Ǭ攘 Y}趷폲ӦӃǶ̗儑,ԚꜶǩﶏ»Ḽ쓸ߐ箠᾽ږċ㷨漊DŽ㷂STLˣ滋Ĭ ˼C碗KǶ̗儑,⢒ԊӍ엷Ϊʤȫ⎊費ʇһ趇輤).

// 攓據 std::copy and std::uninitialized_copy
// oף ImageViewConcept<V1>, MutableImageViewConcept<V2>, ViewsCompatibleConcept<V1,V2>
template <typename V1, typename V2>
void copy_pixels(const V1& src, const V2& dst);
template <typename V1, typename V2>
void uninitialized_copy_pixels(const V1& src, const V2& dst);

// 攓據 std::fill and std::uninitialized_fill
// oף MutableImageViewConcept<V>, PixelConcept<Value>, PixelsCompatibleConcept<Value,V::value_type>
template <typename V, typename Value>
void fill_pixels(const V& dst, const Value& val);
template <typename V, typename Value>
void uninitialized_fill_pixels(const V& dst, const Value& val);

// 攓據 std::for_each
// oף ImageViewConcept<V>, boost::UnaryFunctionConcept<F>
// oף PixelsCompatibleConcept<V::reference, F::argument_type>
template <typename V, typename F>
F for_each_pixel(const V& view, F fun);
template <typename V, typename F>
F for_each_pixel_position(const V& view, F fun);

// 攓據 std::generate
// oף MutableImageViewConcept<V>, boost::UnaryFunctionConcept<F>
// oף PixelsCompatibleConcept<V::reference, F::argument_type>
template <typename V, typename F>
void generate_pixels(const V& dst, F fun);

// 攓據 std::transform with one source
// oף ImageViewConcept<V1>, MutableImageViewConcept<V2>
// oף boost::UnaryFunctionConcept<F>
// oף PixelsCompatibleConcept<V1::const_reference, F::argument_type>
// oף PixelsCompatibleConcept<F::result_type, V2::reference>
template <typename V1, typename V2, typename F>
F transform_pixels(const V1& src, const V2& dst, F fun);
template <typename V1, typename V2, typename F>
F transform_pixel_positions(const V1& src, const V2& dst, F fun);

// 攓據 std::transform with two sources
// oף ImageViewConcept<V1>, ImageViewConcept<V2>, MutableImageViewConcept<V3>
// oף boost::BinaryFunctionConcept<F>
// oף PixelsCompatibleConcept<V1::const_reference, F::first_argument_type>
// oף PixelsCompatibleConcept<V2::const_reference, F::second_argument_type>
// oף PixelsCompatibleConcept<F::result_type, V3::reference>
template <typename V1, typename V2, typename V3, typename F>
F transform_pixels(const V1& src1, const V2& src2, const V3& dst, F fun);
template <typename V1, typename V2, typename V3, typename F>
F transform_pixel_positions(const V1& src1, const V2& src2, const V3& dst, F fun);

// ʹӃӃ맶蒥儻╟Ĭȏ儑Չ뗪뻆稼code>Ԛᘒ굄ʱ겲Ž萐ѕɫת뻼/code>),䓒븶ʓͼ鷫쒻趐ŠӍ켯span>
// oף ImageViewConcept<V1>, MutableImageViewConcept<V2>
// V1::value_type must be convertible to V2::value_type.
template <typename V1, typename V2>
void copy_and_convert_pixels(const V1& src, const V2& dst);
template <typename V1, typename V2, typename ColorConverter>
void copy_and_convert_pixels(const V1& src, const V2& dst, ColorConverter ccv);

// 攓據 std::equal
// oף ImageViewConcept<V1>, ImageViewConcept<V2>, ViewsCompatibleConcept<V1,V2>
template <typename V1, typename V2>
bool equal_pixels(const V1& view1, const V2& view2);

ʹӃ核抓ͼ⎊ˣ稒ꇳ˼CЏͬ載춈. for_each_pixel_positiontransform_pixel_positions 踷o䫵ݵĊǏዘ樎놷,渲늇ϱ˘ҽӃ,բʊӃӚćҪ烎ʏዘZċ㷨,բԚ팳̀Ӑ齃芶.

㲿疵ċ㷨漻Ἤ⩍쏱ʓͼʇ籊DZά遠靚 ˹ν儒뎬遠ʓͼ, ָ儊Ǎ쏱ʽuӐ̮㤮 뻾仰˵, ȧ黊Ӎ쵄x_iterator쓵큋һ億鎲ᖱ퓵ėꈫςһ, ćoբ越Ӎ쾍ʇ1ά遠儮 ȧ黊Ӎ슇һά遠靚 ćoˣ稿ͻኹӃһ趵咻儑, ԋḼ쓵ē綆籔⋣稿ͻᔚY罏⑭뷄ڲ̗Xѭ뷮

һࣕ␩ˣ稻ᰑ餗瘓趔Ӧ儓TLˣ糯 =ȧ copy_pixels 롵瓃 std::copy ɨey,법ߵናͼʇһά遠靚 ɨe˹Ӑ粲ዘ.

m͢, Ӑʱ겻ᶔSTLˣ稌ṩ֘Ԙ. =ȧ,ի累lanar弴ꆷ巔astd::copy 롗껻Ϊ攃︶ѕɫa巔astd::copy , 渶ԿɒԖλア䵄ϱ˘巔astd::copy 롗껻Ϊ攎޷뺅ז횵瓃 std::copy ,淵▖ǩЎς,STL롗껻Ϊ攠memmove儵瓃.

բѹ儽ṻʇ, copy_pixels 롶Ԓ뎬遠儩nterleavedʓͼִ memmove ,법߶Ԓ뎬遠儰lanarʓͼִy趑Չ냦儒봎ア䬻╟攷ǒ뎬遠儩nterleavedʓͼִyʽĒ봎ア䬵ȵȮ

GIL 빌ṩKһͼϱ䦀틣滋Ģeta-঱=ȧʽז)չ֐監زɑ麍픋ˣ剷բԔڠhttp://opensource.adobe.com/gil/download.html僵բʇԚ覆┤ƚ樒嵄ˣ糯⢃듐ի攋ٶȽ萐Ӆ믮


10. ͼϱ

ͼϱʇϱ˘儈݆笊NJӍ쏱˘儓匡՟. ˼롔ڹ錟ꯊ햐疆僋줲┘ζ鹺֐ʍ煮 ˼儸㖵ԋˣꍿ鷫춼ʇɮ⣴εĮ 㽁˔ړ匡Ȩ꜖ؒ굄ǩﶏ¬ͼϱ꜉ٖὓʹӃ. 㶠ʽ儓TLˣ稶슇♗݇輤,渲늇ȝƷ,ͬѹ儇ILˣ稒ⴳ栓擃Ԛͼϱʓͼ(ɏһ횵Ąڈݩ.

䓗Ӄ儽ǶȀ俴,ͼϱʇNά靚⢇҂ꗣҔς儸ńp>

concept RandomAccessNDImageConcept<typename Img> : Regular<Img> {
    typename view_t; where MutableRandomAccessNDImageViewConcept<view_t>;
    typename const_view_t = view_t::const_t;
    typename point_t      = view_t::point_t;
    typename value_type   = view_t::value_type;
    typename allocator_type;

    Img::Img(point_t dims, std::size_t alignment=0);
    Img::Img(point_t dims, value_type fill_value, std::size_t alignment);
    
    void Img::recreate(point_t new_dims, std::size_t alignment=0);
    void Img::recreate(point_t new_dims, value_type fill_value, std::size_t alignment);

    const point_t&        Img::dimensions() const;
    const const_view_t&   const_view(const Img&);
    const view_t&         view(Img&);
};

2ά傻쏱빓춠儒ꇳ:

concept RandomAccess2DImageConcept<RandomAccessNDImageConcept Img> {
    typename x_coord_t = const_view_t::x_coord_t;
    typename y_coord_t = const_view_t::y_coord_t;
    
    Img::Img(x_coord_t width, y_coord_t height, std::size_t alignment=0);
    Img::Img(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);

    x_coord_t Img::width() const;
    y_coord_t Img::height() const;
    
    void Img::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=0);
    void Img::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
};

GIL傻쏱ʓͼoף ImageViewConcept, ⢇ҿɒԲٗݏዘ.

concept ImageConcept<RandomAccess2DImageConcept Img> {
    where MutableImageViewConcept<view_t>;
    typename coord_t  = view_t::coord_t;
};

ӫ樎놷ꍍ쏱ʓͼ⻍쬍쏱uӐ'mutable'腄ҲΪimmutable傻쏱⻊ǺܓIp> Ϡ阸ń/b>

  • RandomAccessNDImageConcept<Image>
  • RandomAccess2DImageConcept<Image>
  • ImageConcept<Image>

ģЍ:

GIL ̡驁ˀ࠼code>image, ˼Ҕ value type (ϱ˘) ΪģॲΊ⇒oף ImageConcept.

template <typename Pixel, \\ PixelValueConcept億㐍
          bool IsPlanar,  \\ planar 법ߠinterleaved 傻쏱
          typename A=std::allocator<unsigned char> >    
class image;

ͼϱ鷫솷Ӑһ趶Ԇ벎ʽ, բԊ鷫엖攆뻲՟ז횶Ԇ뵄ͼϱ. 攆뵄奎늇ז횬 Ĭȏ攜Ԇ벎ʽʇ0, բҢζׅy儊uӐ̮㤮 ʹӃբѹһά遠傻쏱, Ꜷൄˣ稒긼שּׁ ҲΪբѹኹӃ image_view::x_iterator Џዘᩀꬶ費ʇʹӃ轀Ӹ䔓儼code>image_view::iterator. עҢ會Ԇ뎪0儊Ẳ, packed傻쏱ʇҔλ攆뵄,=ȧpackedͼϱԚβuӐ攆뵄λ.


11. ԋʱָʼn傻쏱ꍍ쏱ʓͼ

ͼϱ儑Չ뿕줬 ͨ笨ΐ⺍interleaved/planar鶼ʇģॲΊբʇ᠒놷೶資. Ꜷǩﶏ¬ բ⎊햻ӐԚԋʱ⅄ܵo〞ǒ븶ʵ=,һ趄㿩蹲ݖ趨儂羶䲿꒻趍쏱΄쾬 헪,Ȼ곰䕕ԭ4儑Չ뿕줺͍貲ɮ戴洢똈寵ȧꎊ鈴ΒC儷ꐍͼϱʵϖբ趹愜?ͼϱ쓔شꂫ絻؊⃴ Ѝ?

GIL儀久 dynamic_image, ԊԚԋʱָʼn⎊Ԭͼϱ,ͼϱʓͼ법߈κΆ䋻儇IL鷫쬕 ʇһ越啥:

#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
using namespace boost;

#define ASSERT_SAME(A,B) BOOST_STATIC_ASSERT((is_same< A,B >::value))

// 樒唊傻쏱 Ѝ쯺ϼ/span>
typedef mpl::vector<rgb8_image_t, cmyk16_planar_image_t> my_images_t;

// 䴽蠡ny_image class (법ߠany_image_view)  
typedef any_image<my_images_t> my_any_image_t;

// ʓͼ粲๘Ѝᰒ⊇oĨꍩmage_t/a儊ǒ둹儩
typedef any_image_view<mpl::vector2<rgb8_view_t,  cmyk16_planar_view_t > > AV;
ASSERT_SAME(my_any_image_t::view_t, AV);

typedef any_image_view<mpl::vector2<rgb8c_view_t, cmyk16c_planar_view_t> > CAV;
ASSERT_SAME(my_any_image_t::const_view_t, CAV);
ASSERT_SAME(my_any_image_t::const_view_t, my_any_image_t::view_t::const_t);

typedef any_image_view<mpl::vector2<rgb8_step_view_t, cmyk16_planar_step_view_t> > SAV;
ASSERT_SAME(typename dynamic_x_step_type<my_any_image_t::view_t>::type, SAV);

// Ԛԋʱ攍쏱賒堩t a concrete image at run time:
my_any_image_t myImg = my_any_image_t(rgb8_image_t(100,100));

// Ԛԋʱ脫䍼ϱ, ǰһ趍쏱Ỏ湹
myImg = cmyk16_planar_image_t(200,100);

// 鷫쒻趲딚 ЍԊ綎焚傻쏱,롅׳撻趒쳣Assigning to an image not in the allowed set throws an exception
myImg = gray8_image_t();        // ŗ㶠std::bad_cast

any_imageany_image_view ʇ GIL variant 儗Ӏଠ˼롍蹽һ趷DŽ㰥믵ĵײ㽡鹺͎蒻儀Ѝ᪊潸ʵ=믮 բ趵ײ㽡鵲ǒ븶ז횿鬠բ趗ֽڿ闣黈݄Ɍض耛Ѝ儗Ěȝ.

GIL 儠variant ꍠboost::variant ԚᾖʉϺ܀ˆ (ΒCҲ䋒⽨ӃKć趃뗖),ֻʇԚӐ嗥ꍢoost儊取Ӑ˹⻍쮠Ҳ׮䳵IJ덬LJIL攜ariantלʇͨ齵咻儲ΊԬ,բ趲Ίʇo˔ʐ퀠Ѝ傻PL˦뺷Iʐ⁐(Random Access Sequence). 奒뵄퓿ڊ鵃GIL攜ariantԚ纐ͱ«֐輈ݒ׊鈴.Ƥ腒ꈧς:

template <typename Types>    // MPL ˦뺷Iʈ݆繒span>
class variant {
    ...           _bits;
    std::size_t   _index;
public:
    typedef Types types_t;

    variant();
    variant(const variant& v);
    virtual ~variant();
    
    variant& operator=(const variant& v);
    template <typename TS> friend bool operator==(const variant<TS>& x, const variant<TS>& y);
    template <typename TS> friend bool operator!=(const variant<TS>& x, const variant<TS>& y);

    // 䓀Ѝ T鷫쯸㖵. ȧ黔⻔ڔʐ Ѝ綎焚Բŗ㶒쳣 std::bad_cast
    template <typename T> explicit variant(const T& obj);
    template <typename T> variant& operator=(const T& obj);

    // ͨ齺͔儵ᇰĚȝ빹Ԭ/賒嬽漘˼Cʇ뻻儼/span>
    template <typename T> explicit variant(T& obj, bool do_swap);
    template <typename T> void move_in(T& obj);

    template <typename T> static bool has_type();

    template <typename T> const T& _dynamic_cast() const;
    template <typename T>       T& _dynamic_cast();
    
    template <typename T> bool current_type_is() const;
};

template <typename UOP, typename Types> 
   UOP::result_type apply_operation(variant<Types>& v, UOP op);
template <typename UOP, typename Types> 
   UOP::result_type apply_operation(const variant<Types>& v, UOP op);

template <typename BOP, typename Types1, typename Types2> 
   BOP::result_type apply_operation(      variant<Types1>& v1,       variant<Types2>& v2, UOP op);

template <typename BOP, typename Types1, typename Types2> 
   BOP::result_type apply_operation(const variant<Types1>& v1,       variant<Types2>& v2, UOP op);

template <typename BOP, typename Types1, typename Types2> 
   BOP::result_type apply_operation(const variant<Types1>& v1, const variant<Types2>& v2, UOP op);

GIL儠any_image_viewany_image ʇ variant 儗Ӏຼp>

template <typename ImageViewTypes>
class any_image_view : public variant<ImageViewTypes> {
public:
    typedef ... const_t; // 攓淨immutable Ѝ
    typedef std::ptrdiff_t x_coord_t;
    typedef std::ptrdiff_t y_coord_t;
    typedef point2<std::ptrdiff_t> point_t;

    any_image_view();
    template <typename T> explicit any_image_view(const T& obj);
    any_image_view(const any_image_view& v);

    template <typename T> any_image_view& operator=(const T& obj);
    any_image_view&                       operator=(const any_image_view& v);

    // 屇ʵ=믊Ӎ쵄⎊span>
    std::size_t num_channels()  const;
    point_t     dimensions()    const;
    x_coord_t   width()         const;
    y_coord_t   height()        const;
};

template <typename ImageTypes>
class any_image : public variant<ImageTypes> {
    typedef variant<ImageTypes> parent_t;
public:
    typedef ... const_view_t;
    typedef ... view_t;
    typedef std::ptrdiff_t x_coord_t;
    typedef std::ptrdiff_t y_coord_t;
    typedef point2<std::ptrdiff_t> point_t;

    any_image();
    template <typename T> explicit any_image(const T& obj);
    template <typename T> explicit any_image(T& obj, bool do_swap);
    any_image(const any_image& v);

    template <typename T> any_image& operator=(const T& obj);
    any_image&                       operator=(const any_image& v);

    void recreate(const point_t& dims, unsigned alignment=1);
    void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1);

    std::size_t num_channels()  const;
    point_t     dimensions()    const;
    x_coord_t   width()         const;
    y_coord_t   height()        const;
};

攠variants 巔aapply_operation 롖䐐為ָ樵IJٗ箶ariantͨ齳witchӯԚЍ綎焚ѡԱꏊʵĵĀЍʵ=믮 ҲΪһࣵč쏱ʓͼˣ稶얁əꍏዘʽĿ㉏ߐԱȀ˹Ҕꍄ㰥므Ѝ傻쏱ʓͼϠሬ variant Ѝ傻쏱ʓͼִ奸淨switchӯ뻡Ԭ㉶əĜ摒ꮼp> Variants 儐Ўꄣʽꍵײ〠Ѝʇһւ儮 ˼C兒鷫컡ִ嗲〠Ѝア乾Ԭ,Ϡ刐Բٗ緻롼첩嗲〠Ѝ儒떂,⢔ڴ˻鴡ɏִ嗲〠Ѝ儠operator==, 刵Ȯ variant億숏鷫캯ʽ롖䐐麼븶 Ѝ(ҫ՟ע:variantʇ核怠Ѝ儱䌥)億숏鷫쮕⒲Ңζׅ any_image_view Ї㲣億숏鷫캯ʽ, ア乾Ԭꯊ㖵ԋˣꍏൈ쬲鬶蠷code>any_image Բ롖䐐ɮ⣵IJٗ箼p> Ӑһ壺ܖؒꬠˤȻ any_image_viewany_image 照〠ˆӚ쵄 image_viewimage, 嫊Nj샇⢲낺ף腄code>ImageViewConcept ꍠImageConcept儋銬Ҫdz. ̘ᰵĊǬ˼CuӐϱ˘儷IʸńԚGIL֐⻴攚 "any_pixel" 법ߠ"any_pixel_iterator". բѹ攜ԏ㿉Ҕͨ齠variant 뺖Ɗ取, 嫊Ǖ6׶롵얂ˣ滋ĵ͐笠ҲΪ⻵o땫攃︶ϱ˘ִ Ѝ殠ͼϱ춱ൄˣ稓渃ͨ齠apply_operationʵϖ. ҲNj嬠ꜶͨӃ儲ٗ甚쀠Ѝꍶ Ѝ֮줊ǹ⏭儮 m͢,˹Ӑ傻쏱ʓͼ᤻묠ꜶൄSTLЎʽ儋㷨漕붔 any_image_view̡驁˖ؔذ汾, ᠼcode>copy_pixelsһѹ:

rgb8_view_t v1(...);  // ͼϱʓͼʵ̥
bgr8_view_t v2(...);  // ꍶ1즈ݵč쏱ʓͼ⢇ҾߓЏͬ儴㐡
any_image_view<Types>  av(...);  // ԋʱָʼn傻쏱ʓͼ

// 䓠v1 ア䏱˘擭v2. 
// ȧ黏ዘ⻼賊,Բ⺉걠ҫ䭎㠼/span>
copy_pixels(v1,v2);

// Դ법߄ﱪ(벍슱澕ߩԊǔːЊኵ=믵ļ/span>
// ȧ黋샇⻼賊,Բŗ㶳td::bad_cast
copy_pixels(v1, av);
copy_pixels(av, v2);
copy_pixels(av, av);

빓ڶ鷫쵄ˣ稖ؔجΒCԴ包ʊꏓڱҫƚꍔːІڵč쏱벊Ӎ싣種 =ȧςa儴ꂫ,ʹӃGIL IO)չ,攍쏱ЉϏ·헪⢇Ҵ洢彴Ņ̉Ϻ

#include <boost\gil\extension\io\jpeg_dynamic_io.hpp>

template <typename Image>    // ԊǠrgb8_image_t 법ߠany_image<...>
void save_180rot(const std::string& file_name) {
    Image img;
    jpeg_read_image(file_name, img);
    jpeg_write_view(file_name, rotated180_view(view(img)));
}

ҲΪ˹Ӑ儺漒ԔːЊᵄ鷫얘Ԙ, ˹ҔԶԱҫƚ범ːІڵč쏱ʵ=믮 =ȧ,ςaʇ rotated180_view 儊取:

// ʹӃģॻͼʵϖ
template <typename View> 
typename dynamic_xy_step_type<View>::type rotated180_view(const View& src) { ... }

namespace detail {
    // ͨ齷o碗ຯʽ
    template <typename Result> struct rotated180_view_fn {
        typedef Result result_type;
        template <typename View> result_type operator()(const View& src) const { 
            return result_type(rotated180_view(src)); 
        }
    };
}

// ʹӃ variant ֘Ԙ. Ҕԋʱ傻쏱Ϊ⎊⇒絻ؔːЊᵄͼϱ.
// 絻صč쏱儲 
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type rotated180_view(const any_image_view<ViewTypes>& src) { 
    return apply_operation(src,detail::rotated180_view_fn<typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type>()); 
}

Variants Ӧ能牷ʹӃ(ӈƤ攓ڊ鈴츸渦riantΪ⎊ˣ稩,ҲΪ攓ڶariant儃︶ Ѝ,ˣ稶쒪Њ啥믬բܻᴸ4᠒늱줺͖䐐΄쾴㐡儅╍. 㽁˕␩Ϟֆ, variantʇһ֖ǿ䳵ļ습,˼כꏀ듃K᠒놚淨˙戺͔ːІڽ⎶俊黮. ˼ԊΒCѲ덬⎊ͼϱ׷Ϊ쯺ϒԒ떖ͬһ儷튽ʹӃ,⢇ҿɒԴ洢Ԛͬһ趈݆統֐.


12. 岸뵄Ԫꯊ Typedefs

i뮐ԊǓ꼛儮 GIL儀Ѝܷdz㵄㤬đҔԄ恮 ΪK敢趎ʌ⬠GIL̡驁˴ypedefs,ָϲ᪗쵄ͼϱ, ϱ˘弴ꆷ,ϱ˘樎놷,ϱ˘ҽӃꍏዘֵ.˼C儃샻ױѭςa億㊽:

ColorSpace + BitDepth + ["s|f"] + ["c"] + ["_planar"] + ["_step"] + ClassType + "_t"

Ԛբ/, ColorSpace ҲָʾҪ˘儴ΐ⬠=ȧ rgb, bgr, cmyk, rgba. BitDepth ԊǼcode>8,16,32, Ĭȏ載늇Ξ綹ŕ늽. Ԛ곃挭쓠s ָʾӐ綹ŕ늽,̭쓠f ָʾ衵㊽, ̭쓼code>c ֻʇϠ陣ďዘҽӃʇ⻿ɱ䵄. _planar ָʾϱ˘儗閯罊lanar (Ϡ攓ڠinterleaved). _step ָʾʇ毌첽㤬 ClassType ᭃ奔 _image (ͼϱ, ʹӃ᪗쵄疆䆷), 법߼code>_view (ͼϱʓͼ), 법߼code>_loc (ϱ˘樎놷), 법߼code>_ptr (ϱ˘弴ꆷ), 법߼code>_ref (ϱ˘ҽӃ), _pixel (ϱ˘ֵ). ςaʇʵ=:

bgr8_image_t               i;     // 8λΞ綹ŕ늽(Ξ綹ŗֽک interleaved BGR ͼϱ
cmyk16_pixel_t;            x;     // 16λΞ綹ŕ늽(Ξ綹ųhort) CMYK ϱ˘ֵ;
cmyk16sc_planar_ref_t      p(x);  // 16λӐ綹ŕ늽(Ӑ綹ųhort)planar CMYK儳ҽӃ.
rgb32f_planar_step_ptr_t   ii;    // 빓ڳ2λ衵㊽planar RGB ϱ˘儳tep 弴ꆷ.

ͨ齖趨傻貲 Ѝ,⼾֬騊ǰlanar빊ǩnterleaved),弴경㤨ʇ첽㤻銇毌첽㤩ꍿɱ䐔, GIL ʹӃԪꯊ僱ꗼͬ֊儻銍Ě䦵Ĺ錟:

template <typename ChannelValue, typename Layout, bool IsPlanar=false,                     bool IsMutable=true>
struct pixel_reference_type { typedef ... type; };

template <typename Channel, typename Layout> 
struct pixel_value_type { typedef ... type; };

template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsStep=false,  bool IsMutable=true>
struct iterator_type { typedef ... type; };

template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsXStep=false, bool IsMutable=true>
struct locator_type { typedef ... type; };

template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsXStep=false, bool IsMutable=true>
struct view_type { typedef ... type; };

template <typename ChannelValue, typename Layout, bool IsPlanar=false, typename Alloc=std::allocator<unsigned char> >
struct image_type { typedef ... type; };

template <typename BitField, typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image_type { typedef ... type; };

template <typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image_type { typedef ... type; };

빓됩訖굄Ԫꯊ퓃4鷫찡ckedͼϱ,Ҕ찗5趍貲載붔ƫͼϱ:

template <typename BitField, unsigned Size1, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image1_type { typedef ... type; };

template <typename BitField, unsigned Size1, unsigned Size2, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image2_type { typedef ... type; };

template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image3_type { typedef ... type; };

template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image4_type { typedef ... type; };

template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image5_type { typedef ... type; };

template <unsigned Size1, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image1_type { typedef ... type; };

template <unsigned Size1, unsigned Size2,
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image2_type { typedef ... type; };

template <unsigned Size1, unsigned Size2, unsigned Size3, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image3_type { typedef ... type; };

template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image4_type { typedef ... type; };

template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, 
          typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image5_type { typedef ... type; };

բ/儠ChannelValue ʇ ChannelValueConcept億㐍. ΒC⢲됨Ҫ IsYStep,ҲΪGIL빓ڄڴ淨樎놷ꍊӍ씊毌쵄ָ樴閱⽳䮵촺ƷꍊӍ쿉Ҕ䓏ዘ Ѝ鷫캼p>

template <typename Pixel, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> 
struct iterator_type_from_pixel { typedef ... type; };

template <typename Pixel, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true> 
struct view_type_from_pixel { typedef ... type; };

ͬ֊粲ዘ Ѝ롲ꉺͬ֊儵촺ƷꍊӍ쮠ҲԴӋ弴ꆷ鷫쏠閥Ѝ:

template <typename XIterator> 
struct type_from_x_iterator {
    typedef ... step_iterator_t;
    typedef ... xy_locator_t;
    typedef ... view_t;
};

빓됩Ԫꯊ蹽脫䖸樀Ѝ儒븶벶ึʴ䴽萂儀Ѝ:

template <typename PixelReference, 
          typename ChannelValue, typename Layout, typename IsPlanar, typename IsMutable>
struct derived_pixel_reference_type {
    typedef ... type;  // PixelConcept億㐍
};

template <typename Iterator, 
          typename ChannelValue, typename Layout, typename IsPlanar, typename IsStep, typename IsMutable>
struct derived_iterator_type {
    typedef ... type;  // PixelIteratorConcept億㐍
};

template <typename View, 
          typename ChannelValue, typename Layout, typename IsPlanar, typename IsXStep, typename IsMutable>
struct derived_view_type {
    typedef ... type;  // ImageViewConcept億㐍
};

template <typename Image, 
          typename ChannelValue, typename Layout, typename IsPlanar>
struct derived_image_type {
    typedef ... type;  // ImageConcept億㐍
};

ģԌ滻һʴ,⢊鈴boost::use_default ᣳ֓ς儲뱤. ɏa儼code>IsPlanar, IsStepIsMutable 漊ǠMPL 儲춻㣁ﮠ=ȧ, ςa儴ꂫչʾKȧꎍ蹽脫䊓ͼ儻Ҷȼ溍planar,鹽萂儊Ӎ캼p>

typedef typename derived_view_type<View, boost::use_default, gray_t, mpl::true_>::type VT;

ͨ齊ixelBasedConcept, HomogeneousPixelBasedConceptꍻ銍բ腄ԪꯊģԵo툎ꎻ銍ϱ˘儇IL鷫쨏ዘ,弴ꆷ,樎놷ꍊӍ쩵ď๘ Ѝ:

template <typename T> struct color_space_type { typedef ... type; };
template <typename T> struct channel_mapping_type { typedef ... type; };
template <typename T> struct is_planar { typedef ... type; };

// ͨ齍얊 Ѝ樒彎span>
template <typename T> struct channel_type { typedef ... type; };
template <typename T> struct num_channels { typedef ... type; };

ӐһԪꯊ똕됍Ѝᰬԕ6ʹӃ:

BOOST_STATIC_ASSERT(is_planar<rgb8_planar_view_t>::value == true);

GIL 빌ṩKςPЎʽ儷֎損Ԫꯊ[pixel_reference/iterator/locator/view/image] + "_is_" + [basic/mutable/step]. =ȧ:

if (view_is_mutable<View>::value) {
   ...
}

˹ν 빱 GIL 鷫슇빓ڄڴ淨鷫쬠⢇Ҋ鈴ĚćIL Ѝ, 퓃儊ẲҲ⻊鈴為. =ȧ, һ趼ⵥ儰lanar 법ߠinterleaved傻쏱, step 법ߠ照tep 儒GB ͼϱʇ빱鷫쬠渻銍ѕɫ᤻뵄ʓͼꍐ鄢ʓͼԲ⻊Ǯ


13. I/O )չ

GIL儠I/O )չ̡驁ˌṩK卲㴎傻쏱i/oɨʩ, ֧㖼薖ͼϱ豊쓔غʹ洢, yһ֖豊Ҫl퓏๘兒⺼p>
  • JPEG: ΪKʹӃJPEG ΄쾬 Ҫ༺쎄쾠gil/extension/io/jpeg_io.hpp. 嫊Lj繻ʹӃԋƚָʼn傻쏱, ģҪ༺쎄쾼code>gil/extension/io/jpeg_dynamic_io.hpp. ģҪ᠒벢l퓿⬩bjpeg.lib (Ԛ͸վ http://www.ijg.orgԵo ģҪԚ༺삷Ќjpeglib.h.

  • TIFF: ΪKʹӃ TIFF ΄쾬 Ҫ༺쎄쾠gil/extension/io/tiff_io.hpp. 嫊Lj繻ʹӃԋƚָʼn傻쏱, ģҪ༺쎄쾠gil/extension/io/tiff_dynamic_io.hpp . ģҪ᠒벢l퓿⬩btiff.lib (Ԛ͸վ http://www.libtiff.org). ģҪԚ༺삷Ќtiffio.h.

  • PNG: ΪKʹӃ PNG ΄쾬 Ҫ༺쎄쾠gil/extension/io/png_io.hpp. 嫊Lj繻ʹӃԋƚָʼn傻쏱, ģҪ༺쎄쾠gil/extension/io/png_dynamic_io.hpp . ģҪ᠒벢l퓿⬩bpng.lib (Ԛ͸վ http://www.libpng.org). ģҪԚ༺삷Ќpng.h.

ģ⢲됨Ҫಗ˹Ӑբꯊ,◰ģҪ儼俉.բ/ʇһի擽PEG I/O俊PI (ʹӃ"tiff" 법ߠ"png" ̦뻼code>"jpeg" 촿Ɋ鈴Ƥ˻儺:

// 僵햸樂羶儊PEG΄쾵Ŀꍳ䶈.
// ȧ黖趨·ĊPEG΄쾲뺏糯Բŗ㶳td::ios_base::failure
point2<std::ptrdiff_t> jpeg_read_dimensions(const char*);

// കՖ趨儊PEG΄쾵Ď춈䴽荼ϱ,⢇ҼӔ؏ዘ.
// ȧ黊PEG╟I/O)չ⻖糖ͼϱ儑Չ뿕줺͍貲ɮ戩롼䷢᠒봭γ.
// ȧ黖趨·ĊPEG΄쾲뺏糯법ߺ͍쏱ָ樵đՉ뿕줺͍貲ɮ戲뼦ȝ,Բŗ㶳td::ios_base::failure. 
template <typename Img> void jpeg_read_image(const char*, Img&);

// കՖ趨儊PEG΄쾵Ď춈䴽荼ϱ,⢇ҼӔ؏ዘ,
// ȧӐᘒꔲִѕɫ᤻뺍ͨ倱任.
// ȧ黊PEG╟I/O)չ⻖糖ͼϱ儑Չ뿕줺͍貲ɮ戩롼䷢᠒봭γ.
// ȧ黖趨·ĊPEG΄쾲뺏糯법߷≺恎ļγ,Բŗ㶳td::ios_base::failure.
template <typename Img>               void jpeg_read_and_convert_image(const char*, Img&);
template <typename Img, typename CCV> void jpeg_read_and_convert_image(const char*, Img&, CCV color_converter);

// കՖ趨優peg΄쾃볆,쏱쓔ص햸樵ĊӍ얐.
// ȧ黊PEG╟I/O)չ⻖糖ͼϱ儑Չ뿕줺͍貲ɮ戩롼䷢᠒봭γ.
// ȧ黖趨·ĊPEG΄쾲뺏糯법ߺ͊Ӎ언樵đՉ뿕줺͍貲ɮ戲뼦ȝ,법ߎ춈⻆晃, Բŗ㶳td::ios_base::failure.
template <typename View> void jpeg_read_view(const char*, const View&);

// കՖ趨優peg΄쾃볆,쏱쓔ص햸樵ĊӍ얐,⢖䐐ᘒ굄ѕɫ᤻먻╟ͨ倱任).
// ȧ黊PEG╟I/O)չ⻖糖ͼϱ儑Չ뿕줺͍貲ɮ戩롼䷢᠒봭γ.
// ȧ黖趨·ĊPEG΄쾲뺏糯법ߎ춈⻆晃, Բŗ㶳td::ios_base::failure.
template <typename View>               void jpeg_read_and_convert_view(const char*, const View&);
template <typename View, typename CCV> void jpeg_read_and_convert_view(const char*, const View&, CCV color_converter);

// കՖ趨儃볆,Ӎ촦䢵eg΄쾖
// ȧ黊PEG╟I/O)չ⻖糖ͼϱ儑Չ뿕줺͍貲ɮ戩롼䷢᠒봭γ.
// ȧ黴洢΄쾊簜,Բŗ㶳td::ios_base::failure .
template <typename View> void jpeg_write_view(const char*, const View&);

// Ő揪peg恈ኇ֧㖖趨儊Ӎ쀠Ѝ 
template <typename View> struct jpeg_read_support {
    static const bool value = ...;
};

// Ő揪pegȫʇ֧㖖趨儊Ӎ쀠Ѝ 
template <typename View> struct jpeg_write_support {
    static const bool value = ...;
};

ȧ黊鈴毌썼ϱ)չ, ȷᣰ캬΄쾠"jpeg_dynamic_io.hpp" ,淵Dz늇 "jpeg_io.hpp". 㽁¯σ淨罷謶ԓڶͼϱ빖糖ςa監ؔغ

// 䲿ꖸ樵ĊPEG΄쾬 ѡԱͼϱ Ѝ֐麼븶ꍍ쏱΄쾀ЍԚѕɫ亍ͨ倀Ѝ즈ݵĀЍ
// കՍ쏱΄쾵Ď춈䴽蕢֖ Ѝ傻쏱.
// ȧ黸趨儀ЍꍴŅ̎ļ Ѝ⻼賊,Բŗ㶒쳣 std::ios_base::failure .
template <typename Images> void jpeg_read_image(const char*, any_image<Images>&);

// കՖ趨優peg΄쾃묠ѵᇰʵ=믵ĊӍ촦䢆4.
// ȧ黌/O)չ⻖糖屇ʵ=믵ĊӍ쀠Ѝ,법ߴ包΄쾊簜,Բŗ㶒쳣std::ios_base::failure  
template <typename Views>  void jpeg_write_view(const char*, any_image_view<Views>&);

ɏa˹Ӑ儷漶ԲΊcode>std::string ꍠconst char*ʵϖK֘Ԙ儰汾


14. ʾ=亂뼯a>

ϱ˘춱ൄʾ=亂뼯a>

ςaʇһի攏ዘ,ָիꍒ퓃 Ѝ儲ٗ紖p>
rgb8_pixel_t p1(255,0,0);     // 䴽躬ɫ儠RGB ϱ˘
bgr8_pixel_t p2 = p1;         // RGB ꍠBGR ʇ즈ݵĬͨ倖笑롱뇡岸ē㉤. 
assert(p1==p2);               // p2 Ҳʇꬉ뵄.
assert(p2[0]!=p1[0]);         // operator[] 僵튇ͨ倖嵄ί-䎐⠨ҲDŽڴ洎)
assert(semantic_at_c<0>(p1)==semantic_at_c<0>(p2)); // բʇȧꎱȽρꬉ덨倵ķ
get_color(p1,green_t()) = get_color(p2,blue_t());  // ͨ倖笑ԍ蹽uㆷIʼ/span>

const unsigned char* r;
const unsigned char* g;
const unsigned char* b;
rgb8c_planar_ptr_t ptr(r,g,b); // 䓃︶ѕɫa儳ָի鷫죯nst planarָի

rgb8c_planar_ref_t ref=*ptr;   // ᄚĒ퓃 Ѝһѹ, 累lanarָի퓃絻ؒ븶planarҽӃ Ѝ

p2=ref; p2=p1; p2=ptr[7]; p2=rgb8_pixel_t(1,2,3);    // planar/interleaved 儒퓃ꍖ倠ЍꍠRGB/BGR  Ѝ儑Չ떮줿ɒԗԓɵĻ캏ʹӃ

//rgb8_planar_ref_t ref2;      // ᠒봭γ: ҽӃuӐĬȏ鷫켯span>
//ref2=*ptr;                   // ᠒봭γ: 㣁ի儽ⒽӃ⻄ܸ㸸照ҽӃ
//ptr[3]=p1;                   // ᠒봭γ: ⻄ܸı䳣ָի儵ڴ趏ዘ
//p1 = pixel<float, rgb_layout_t>();// ᠒봭γ: ⻼賊傻貲ɮ卯/span>
//p1 = pixel<bits8, rgb_layout_t>();// ᠒봭γ: ⻼賊儑Չ뿕줨ˤȻćͨ伀턿Ϡͬ)
//p1 = pixel<bits8,rgba_layout_t>();// ᠒봭γ: ⻼賊儑Չ뿕줨촊鋼ꬓred, green ꍠblue ͨ倩

ςaʇ纐ʹꂫȧꎊ鈴ϱ˘:

template <typename GrayPixel, typename RGBPixel>
void gray_to_rgb(const GrayPixel& src, RGBPixel& dst) {
    gil_function_requires<PixelConcept<GrayPixel> >();    
    gil_function_requires<MutableHomogeneousPixelConcept<RGBPixel> >();

    typedef typename color_space_type<GrayPixel>::type gray_cs_t;
    BOOST_STATIC_ASSERT((boost::is_same<gray_cs_t,gray_t>::value));

    typedef typename color_space_type<RGBPixel>::type  rgb_cs_t;
    BOOST_STATIC_ASSERT((boost::is_same<rgb_cs_t,rgb_t>::value));

    typedef typename channel_type<GrayPixel>::type gray_channel_t;
    typedef typename channel_type<RGBPixel>::type  rgb_channel_t;

    gray_channel_t gray = get_color(src,gray_color_t());
    static_fill(dst, channel_convert<rgb_channel_t>(gray));
}

// ʹӃģʽ儊:

// ѻҶȖ秦뻎ꂇRϱ˘ֵ,բ趏ዘλӚ16λinterleavedͼϱ質5,5)䦺
bgr16_view_t b16(...);
gray_to_rgb(gray8_pixel_t(33), b16(5,5));

// Ѹλ뒶ȼ捼ϱ儵ڒ븶ϱ˘䦴⵽32λplanar RGB ͼϱ儵ڎ帶ϱ˘䦺
rgb32f_planar_view_t rpv32;
gray8_view_t gv8(...);
gray_to_rgb(*gv8.begin(), rpv32[5]);

սȧʾ=ᭃ組,Դꍄﱪ儀Ѝ漿ɒԊǒ퓃벖嬠planar 베interleaved,ֻҪ˻C綹ϠPixelConceptMutablePixelConcept 儒ꇳ.

ʹӃಈ뻺㥇貼쏱ア䠼/a>

왶莒CҪʹӃ栺˶ԍ쏱䦀儀鳤ʇ2K+1 x 2K+1 ϱ˘, բѹΒC蒪Ԛͼϱ儱߽帔趏ዘ儌, ςaʇ˼儊取:

ΒC䴽蒻躉촳ά戟č쏱, Ȼ곎҃NJ鈴 subimage_view 䴽蒻趇㲣דʓͼ,׳ɏ퇎듚Դʓͼ質k,k)䦬䳐ẍ srcһւ,׮곎҃NJ鈴 src ア䵽ʓͼ監뮠ȧ黛߽獻㤐蒪㵊컯, ΒCԊ鈴fill_pixelsʵϖ. ςaΒCʹӃˣ稼code>copy_pixels儼⻯ʵϖ:

template <typename SrcView, typename DstImage>
void create_with_margin(const SrcView& src, int k, DstImage& result) {
    result.recreate(src.width()+2*k, src.height()+2*k);
    copy_pixels(src, subimage_view(view(result), k,k,src.width(),src.height()));
}

(עҢ擭image::recreateҪሼcode>operator=蟐纜栬 ҲΪ곕ߒꖴһ趲뱘Ҫ兒鷫쩮 ɏa儴ꂫ⻽把ӃӚ⻍쑕ɫ䬲덬ϱ˘ɮ戩⻍콡鷚planar 법ߠinterleaved)傻쏱;渴ҋ쒲ʇӅ믵ĮGIL֘K std::copy, 洼Ί튇}趔ڐЄ郻Ӑ̮㤵ďͬinterleaved傻쏱儊Ẳ,˼ֻʇ첵嵄巔amemmove. 攓ڠplanar ͼϱ,攃︶ͨ倖䐐 memmove. ȧ黁ͼϱuӐ̮㤨ΒC儇鿶Lj紋),攃ΒCﵷӃ memmove . 屆䖐儒븶ͼϱuӐ̮㤬 ˼롊鈴ǡ춵ċ弴ꆷ(轀Ӹ䔓儱άͼϱ弴ꆷ롶ԃ첩). כꏿ삇캍ԋʱ儲Ί˼롑ᔱ׮וּķ.

ֹ״ͼ

ֹ״ͼͨ齼Ƌヿ趏ዘֵ㶏ֵĴΊ彮 ςa儋㷨Ҕ뒶ȼ捼ϱ(һά儩Ϊ⎊⎪ֻӐ뒶ȼ淨ϱ˘ֵԗ껻Ϊջʽ:
template <typename GrayView, typename R>
void grayimage_histogram(const GrayView& img, R& hist) {
    for (typename GrayView::iterator it=img.begin(); it!=img.end(); ++it)
        ++hist[*it];
}

ʹӃ boost::lambda ꍠGIL儠for_each_pixel Ԋ鵃ΒC儋㷨輽䴕:

template <typename GrayView, typename R>
void grayimage_histogram(const GrayView& v, R& hist) {
    for_each_pixel(v, ++var(hist)[_1]);
}

var_1 漊Ǡboost::lambda 攜ԏ㬠⢇Ҽcode>for_each_pixel 롵瓃 std::for_each . ΪK솋戟Ė間ͼ, ΒCԊ鈴ͼϱ儻Ҷȼ抓ͼ巔Eσ淨罷軂p>

template <typename View, typename R>
void luminosity_histogram(const View& v, R& hist) {
    grayimage_histogram(color_converted_view<gray8_pixel_t>(v),hist);
}

ԏᏂaբѹ巔O⸶罷軂p>

unsigned char hist[256];
std::fill(hist,hist+256,0);
luminosity_histogram(my_view,hist);

ȧ黎҃Ǐ벩ﴍ쏱׳ɏ퇱00x100儇蓲嚶ͨ倵Ė間ͼ:

grayimage_histogram(nth_channel_view(subimage_view(img,0,0,100,100),1),hist);

Ԛբ趹֐, uӐϱ˘兒ꍶ億ڴ淖Ť,漊ǖὓ♗ݔ䊓ͼ粲ዘ, Դʓͼ֧㖈κεđՉ뿕줺͍貲ɮ戩 Ԛ鉏ҲԊǰlanar 베interleaved儮

ʹӃͼϱʓͼ

ςa儴ꂫ˵÷KʹӃͼϱʓͼ傻:

jpeg_read_image("monkey.jpg", img);
step1=view(img);
step2=subimage_view(step1, 200,300, 150,150);
step3=color_converted_view<rgb8_view_t,gray8_pixel_t>(step2);
step4=rotated180_view(step3);
step5=subsampled_view(step4, 2,1);
jpeg_write_view("monkey_transform.jpg", step5);

բͼϱ儽ṻʇ:

monkey_steps.jpg

עҢ錄 uӐϱ˘兒,˹Ӑ儹䗷漊鼓Ԛ jpeg_write_viewɏa. ȧ黎҃Ǖ붔step5巔ucode>luminosity_histogram,뒲ʇսȷ儮


15. )չGIL

ģԶ蒥ה캵ďዘ弴ꆷ,樎놷,ͼϱʓͼ,ͼϱ,ͨ倀Ѝ,ѕɫ亍ˣ種 Ģ傻쏱Ԏ듚䅅̉Ϭ jpeg΄쾖 internet֐億㸶嗥╟ʇͪȫꏳɵč쏱,=ȧ Mandelbrot 쯺Ϭ ֻҪ˻CoףϠ陣ĸńdz, ˼CɒԊ鈴ґӐ儇ILˣ種㶠ʽբѹ儀久⢲됨Ҫ脫䒑Ӑ儴ꂫ, բ)չҲԔچ䋻億㿩屖

樒吂儑Չ뿕줼/a>

y趑Չ뿕줎듚һ趵嶀載ļ֐. ΪK̭쓒븶Ђ儑Չ뿕줬 ֻҪア䎄쾠(⎼렼a class="el" href="rgb_8hpp.html">rgb.hpp) , ⢐޸ď๘儲﷖촿ɮ ȧ黃㐨Ҫѕɫ᤻뵄֧㖬ģҪ樒吂儑Չ뿕줺͒ѓđՉ뿕줖儱任ꯊμ렣olor_convert.h). ΪK罱㬠ģҪλЂ儑Չ뵄䶨ҥϱ˘,ָի,ҽӃꍊӍ쵄typedef (⎼렴ypedefs.h).

樒吂傻貲 Ѝ

㶠ʽ儇鿶ςģ⻐蒪樒吂傻貲 Ѝ, ģNJ鈴˼C卑Ѻ

typedef pixel<double,rgb_layout_t>   rgb64_pixel_t;    // 64 λ RGB ϱ˘ 
typedef rgb64_pixel*                 rgb64_pixel_ptr_t;// ָϲ64λ interleaved 儊
typedef image_type<double,rgb_layout_t>::type rgb64_image_t;    // 64Wλinterleaved ͼϱ

ȧ黃㏫樒嗔캵č貲 Ѝ, ģҪΪ˼̡驀Ѝchannel_traits 儌ػﰦᾠ(⎼렼a class="el" href="channel_8hpp.html">channel.hpp). ȧ黃㐨ҪԚЂ傻貲 Ѝꍒѓč貲 Ѝ֮줽萐ת뻬 ģҪ樒峬ʽchannel_convert監ؔذ汾.

֘Ԙѕɫ᤻뼯a>

왈焣Ҫ樒嗔캵đՉ뱤뻬 =ȧ,ģҪʹӃѕɫŤփ΄쾊取輸ߖʁ﵄ѕɫ᤻뮠һࣇ鿶ς, ģֻʇ롔ڄ㐩̘ʢ儇鿶ς֘樒嘔ɫ᤻묠淵䋻儇鿶ԲʹӃGIL億숏ʵϖ. ςaʇһ趑Չ뱤뻖ؔصĊ, Ԛ뒶ȍ쵄ʱ겊鈴ה樒嘔ɫ᤻묠淵䋻ǩﶱ㳖⻱集p>
// ʹӃ GIL 億숏儊取 
template <typename SrcColorSpace, typename DstColorSpace>
struct my_color_converter_impl
  : public default_color_converter_impl<SrcColorSpace,DstColorSpace> {};

// ģֻҪ樒嗔캐蒪儌ػϖ
// (Ԛբ/,ȧ黃ﱪʇ뒶ȼ淨ͼϱ,萐仲ꩼ/span>
template <typename SrcColorSpace>
struct my_color_converter_impl<SrcColorSpace,gray_t> {
    template <typename SrcP, typename DstP>  // PixelConcept 億㐍
    void operator()(const SrcP& src, DstP& dst) const {
        default_color_converter_impl<SrcColorSpace,gray_t>()(src,dst);
        get_color(dst,gray_color_t())=channel_invert(get_color(dst,gray_color_t()));
    }
};

// 䴽蒻趑Չ뱤뻶ԏ㬓OڗԶ蒥儊取屖/span>
struct my_color_converter {
    template <typename SrcP, typename DstP>  // PixelConcept億㐍
    void operator()(const SrcP& src,DstP& dst) const { 
        typedef typename color_space_type<SrcP>::type SrcColorSpace;
        typedef typename color_space_type<DstP>::type DstColorSpace;
        my_color_converter_impl<SrcColorSpace,DstColorSpace>()(src,dst);
    }
};

GIL儑Չ뱤뻺ʹӃѕɫ᤻놷攏㗷Ϊᵄ⎊Ԛբ/ģԑᔱה캵đՉ뱤뻆綔ϳ:

color_converted_view<gray8_pixel_t>(img_view,my_color_converter());

樒吂傻쏱ʓͼ

ͨ齶蒥ϱ˘P뱈ᵄ뺖Ƭ 법ߍ蹽퓃Џዘ᤻묠ģɒԶ蒥ה캵ďዘ弴ꆷ,樎놷ꍊӍ쮠=ȧ, ȃΒC⩿䕢趺color_converted_view (һ趍쏱餳赬糯 ͨ齒븶ָ樵č쏱ʓͼ,絻ؒ븶Ђ傻쑹儊Ӎ쬠ֻʇԚϱ˘烎ʉϽ萐Kѕɫ᤻멵Ċ取. ʗψΒCҪ樒咻趼code>PixelDereferenceAdaptorConcept億㐍; ʇһ趔ڶԏዘ弴ꆷⒽӃ儊Ẳ巔oķo. 巔ucode>color_convert ת뻎ꄿ᪏ዘ Ѝ:

template <typename SrcConstRefP,  // Դϱ˘儳ҽӃ 
          typename DstP>          // Ŀ᪏ዘֵ(PixelValueConcept億㐍)
class color_convert_deref_fn {
public:
    typedef color_convert_deref_fn const_t;
    typedef DstP                value_type;
    typedef value_type          reference;      // ֻ惲ⒽӃ
    typedef const value_type&   const_reference;
    typedef SrcConstRefP        argument_type;
    typedef reference           result_type;
    BOOST_STATIC_CONSTANT(bool, is_mutable=false);

    result_type operator()(argument_type srcP) const {
        result_type dstP;
        color_convert(srcP,dstP);
        return dstP;
    }
};

ͨ齵瓃ͼϱʓͼ儳ɔắʽadd_deref,Ԛϱ˘퓃儊Ẳִ為( Ѝʇderef_t),ΒCԹ錟Ђ傻쏱ʓͼ. Ԛբ/, 為ִ齉͊ǑՉ뱤뻺

template <typename SrcView, typename DstP>
struct color_converted_view_type {
private:
    typedef typename SrcView::const_t::reference src_pix_ref;  // SrcViewϱ˘儳ҽӃ
    typedef color_convert_deref_fn<src_pix_ref, DstP> deref_t; // ִѕɫ᤻뵄퓃ʊŤƷ
    typedef typename SrcView::template add_deref<deref_t> add_ref_t;
public:
    typedef typename add_ref_t::type type; // ѕɫ᤻뺳儊Ӎ쀠Ѝ
    static type make(const SrcView& sv) { return add_ref_t::make(sv, deref_t()); }
};

׮곎҃ǵĺ color_converted_view ɒԼⵥ䓔䊓ͼ鷫쒻趾ѕɫ᤻뵄ʓͼ:

template <typename DstP, typename View> inline
typename color_converted_view_type<View,DstP>::type color_convert_view(const View& src) {
    return color_converted_view_type<View,DstP>::make(src);
}

(ʵ습đՉ뱤뻓뵣贔ӬҲΪˤȻԊӃ맖趨ѕɫ᤻뵄為,嫊Ǖ⸶⎊튇ᵄ). ⎼뇉L팳̬ ć/Ӑһ趍蹽樒卡ndelbrot쯴包Ģͼϱʓͼ儊.


16. רA켊彎a>

䴽蒽Ӄ龜a>

Ӑʱ겐蒪䴽蒻趴ꀭ , Ӄ4ᭊ趖趨攏㵄ҽӃ. բ罃淨=דʇGIL儰lanarЍᰵďዘҽӃ(planar_pixel_reference) ꍠGIL傻貲ҽӃד Ѝ.ʩբѹ儒븶龜퀠Ҫһ켇ɮ ƤΊ̢֮һǬ 弴ꆷ퓃儷廘ֵʇһ趒퓃龜⊇һ趁يᶔϳ:

struct rgb_planar_pixel_iterator {
   typedef my_reference_proxy<T> reference;
   reference operator*() const { return reference(red,green,blue); }
};

屒븶ꯊ풔䏱˘Ϊ⎊貧ȫբѹһ趵촺Ʒ퓃ɺ㉵āيᶔϳ儊Ẳ,Ί̢揖K:

template <typename Pixel>    // MutablePixelConcept億㐍
void invert_pixel(Pixel& p);

rgb_planar_pixel_iterator myIt;
invert_pixel(*myIt);        // ᠒봭γ!

C++ ⢲딊攁يᶔϳdzҽӃ,淨罷芇:

  • 攋銬儒퓃龜ϳʹӃconstʎ綹

template <typename T>
struct my_reference_proxy {
    const my_reference_proxy& operator=(const my_reference_proxy& p) const;
    const my_reference_proxy* operator->() const { return this; }
    ...
};

  • ʹӃ⻍쵄Ѝᰖ芾⻿ɱ䵄ꍳ儒퓃(법߻銍ģॲΊ㣁)

  • ʹӃ㣁ʎ綬蒥弴ꆷ儒퓃 Ѝ:

struct iterator_traits<rgb_planar_pixel_iterator> {
   typedef const my_reference_proxy<T> reference;
};

嚶֘Ҫ載ʌ⊇ҪΪswap̡驕붔ģ儒퓃 監ؔذ汾, Ĭȏ儠std::swap ⻻ᕽȷ監䐐, ģᘐ늹Ӄһ趕敿監倠Ѝ׷ΪYʱ攏㮠һ躉켓贔ӵĎʌ⊇ԚӐSTL儊取֐, ꯊode>swap ⻄ܕ툷ꏷ資巔i Ψһ儴늩ǔڼcode>stduu䖐֘Ԙբ趷:

namespace std {
   template <typename T>
   void swap(my_reference_proxy<T>& x, my_reference_proxy<T>& y) {
      my_value<T> tmp=x;
      x=y;
      y=tmp;
   }
}

׮곒뵣Ҫ쇗ᬠ龜풽Ӄ儹錟ꯊア乾Ԭ漊LJ㿽ᴵĬ游㖵ԋˣ絆ljᴵĮ

攓ډσ淨淽ีĽ蒩՟,Dave Abrahams, Sean Parent ꍠAlex ,ΒCᭊ.


17. ۼ/a>

Ҫ쇗ᇉLӐҔς5趉輆Ŀ᪺

  • 纐ͮ 䓍쏱ˣ滋ĽǶȳ錚ͼϱ儱폖, բʹ僩ꂫֻҪʩһ䎾͊ʓOڋ銬傻쏱 Ѝ.
  • Š. ˙戊ǿ≨솵Ļ鴡. ṩ儷ꐍˣ稔ںܶǩﶏ¬Ƥ˙房ɒԺ͕붔ij֖̘樍쏱豊ʖ亂돠懃.
  • i뮐Ԯ ᠒놚⎊ζ儋ٶȺܿ쬠嫊Ǵꂫ俊黮ʜ彑ϖصďޖƬ GILԊ⎊픚ԋʱ欠բֻʇ一亞儐Ԅ܋ʧ.
  • 久. ʵ슉χIL儃︶鷫춼ʇ久靚ֻҪ綹χIL腄Ҫdz, ɒԹ錟Ђ傻貲 Ѝ, ѕɫ䬲쾖,弴ꆷ,樎놷,ͼϱʓͼꍍ쏱.
  • 즈ݐԮ GILɨ솎ꓔL儒븶⹳䮠ϱ˘䦀ҔʹӃSTL儋㷨, ⢇Ғ⌘ᰵė戀ի攐ԵēŻﮠGILԺ͒ѓЍ쏱숫儂㏱˘ʽ놰餗箼/li>

Generated on Thu Nov 8 21:53:19 2007 for Generic Image Library by  doxygen 1.4.4