GILɨ솖髒
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 Ѝ儺
ҪעҢܵĐԆ뵼ւĩ兒հ. GIL̡駔č쏱ģЍԓ涔ȧς儱仯:
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>
ģЍ:
GIL ̡驁ˠ
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ԊʹӃĚĕ됍ꍸᵣЍΪͨ倀Ѝ. Ҳ䋆䏠闡ͱຍ綎琅ϢԊ鈴
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>;
};
һ趍貲 Ѝԗ껻ΪƤ˻傻貲 Ѝ:
template <ChannelConcept Src, ChannelValueConcept Dst> concept ChannelConvertibleConcept { Dst channel_convert(Src); };
עҢ擭 עҢ彋㷨ܐ蒪攍貲 Ѝʩ쓸춠儒ꇳ,=ȧҪ֧㖋㊵ԋˣ. Ϡ阸ń/b>
ģЍ: ˹ӐĚĕ됍ꍸᵣЍ漊Ǔ組ͨ倀Ѝ, 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;
빓ڄڽ萍ᰵč貲 Ѝ儗ֵꍗֵ, ꍕĚͱൄί-ֵ綎璻ւ,Ҳ촍蹽
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ʇ즈ݵĮ閣긅Į:
ģЍ:
屇ൄGIL֧㖈珂儑Չ뿕줺 Ϊһ趀헓,ς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儓䎐⮠=ȧ
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 億㐍ᘐ댡騶 ȧ黁햖ѕɫ빵đՉ뿕줊Ǐൈ靚 ⢇҆䒪˘ Ѝʇԗ껻靚ćo˼CǼ賊儮 Models: GIL ̡驁ˍ얊ѕɫ빸ń샇儒ꋘ Ѝ漊Ǐͬ儩億㐍.
namespace detail { template <typename Element, typename Layout, int K> struct homogeneous_color_base; }
GILϱ˘, planarϱ˘ҽӃꍰlanerϱ˘弴ꆷ漊NJ鈴ѕɫ빸ńϖ儮 ˣ稚 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ʇ
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ٗ緻
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 ꍠ Ϡ阸ń/b>
ģЍ:
㣓oďዘʇͬ֊ϱ˘, Ƥֵl䦴┘һư. ΪKբ趄﵄, GIL̡驁˽ṹ
// ʇ 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鲏퍬ѹ監倠Ѝ (
// ʇ 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;
עҢ彬 ꍽṹ Ӑʱ겏ዘ傻貲⻊ǗֽڶԆ뵄. =ȧ'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 ˣ稚
숈돱˘ʇ
// ȧꎷ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
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> {};
Ϡ阸ń
ģЍ:
GILͨ齇ڽ資ϱ˘ָի 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;
ҲΪ
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ʇ᠒놚穴鬋鍆 ϱ˘ʊŤƷ弴ꆷʊŤƷǏዘ儰칼Ʒ. ϱ˘ʊŤƷ儼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> {};
Ϡ阸ń
ģЍ: GIL ̡驁˼踶 IteratorAdaptorConcept億㐍:
ϱ˘퓃ʊŤƷϱ˘퓃ʊŤƷʇһ趒딪ꯊɒԶԒ븶ϱ˘弴ꆷ퓃. ˼儲Ί퀠ЍʇȎҢ質八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 ̡驁˼踶
GIL ͨ噤ⒽӃʊŤƷʵϖͼϱʓͼ儑Չ뱤뻬 법ߵo폱˘嚮趍貲儻ҶȖ寵ͨ齈Βⵄꯊ뻬 퓃ʊŤƷʵԓA䊵ϖĢͼϱʓͼ, =ȧ Mandelbrot 쯮 Step 弴ꆷӐʱ겎҃Ǐ㍻Ҕ奎벽㤶費ʇϱ˘ָ樵IJᩀꏱ˘弴ꆷ,ς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 弴ꆷ儠
ΪKĜ黑ԗֻ◖횏⇰弴ꬠ빴ᵼ了籐ʇ MemoryBasedIteratorConcept 億㐍. 빓ڄڴ淨弴ꆷӐһ趄ڔڵĴ洢奎묠λ법ߗֽڮ ˼ᘐ댡驏愜: y趴洢奎뵄λʽ(1벸), 屇ൄ⽳䬠}趵촺Ʒ֮줻銍䦴ⵥλ齉+, ָ樻銍䦴ⵥλ뵄ҽӃ. ˼빱ؐ댡騶ʹ僵촺Ʒǰ붨뮠ꯊode>memunit_advanced ꍠ 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̡駔ďዘ弴ꆷ,樎놷ꍍ쏱ʓͼ億㐍漊ǖ糖 Ϡ阸ń/b>
ģЍ:
˹ӐGIL屇̡駔Ļ銍Ě䦵ĵ촺Ʒ漊Ǡ
template <typename I> // ʇ MemoryBasedIteratorConceptꍠHasDynamicXStepTypeConcept億㐍 typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step);
GIL 빌ṩK ϱ˘樎놷樎놷ԊԚ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ꍙ攓淨
concept HasDynamicYStepTypeConcept<typename T> {
typename dynamic_y_step_type<T>;
where Metafunction<dynamic_y_step_type<T> >;
};
GIL̡駔ċ銬樎놷ꍍ쏱ʓͼ漊Ǡ Ӑʱ겶ԒԖ趨攜莻Ʒꍍ쏱ʓͼ,Ҫ攻똺͙罏ⵄꬒ娀툧,GIL̡驁˶Ի덼ϱʓͼ儺). բѹ攜莻ƷꍊӍ챘ʇԻ뵄:
concept HasTransposedTypeConcept<typename T> {
typename transposed_type<T>;
where Metafunction<transposed_type<T> >;
};
GIL̡駔ċ銬攜莻ƷꍊӍ춼ʇ
GIL攜莻Ʒ♗ݵĀЍ漊Ǡ
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>
ģЍ:
GIL ̡驁ˠ
template <typename StepIterator> // ʇStepIteratorConcept, MemoryBasedIteratorConcept億㐍 class memory_based_2d_locator;
ӉӚ樎놷ʹӃK빱ȝꍳtep弴ꆷ疿굄ģʽ, ˹ҔΒCԴ包ϱ˘儴洢鵃쓸䔓攜莻Ʒ. 麼묠ΒCԶԋ罏ⵄ弴ꆷᔱ, =ȧᩀꍬһ粲ዘ. ʹӃբ֖疿굄ģʽ脛ˎ҃NjĖ֑ᔱ兒Ʉܺ
屈묓u璲Ԍṩ˼Cה캶薆儠x-iterator. ςaeʶ儒븶=דʇһ趵촺ƷʊŤƷ,岸ⒽӃ儊ẲԽ萐ѕɫת뻮
ָ樒븶ˮƽ弴ꆷ
բѹΒ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ͼϱ攜莻Ʒ,ֻʇ༺쒻趖菲ϱ˘ưʼλփ儂㖸իꍒ븶ʽ㐡儕늽, ל鯨趗ֽڮ
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һ䎊ǔڠ 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ף
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>
ģЍ:
GIL ̡駔ļcode>ImageViewConcept 億㐍ʇ
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
ͼϱʓͼ֮줿ɒԗԓɗ麇(⎼렼a class="el" href="gildesignguide.html#MetafunctionsDG">12. ʹӃԪꯊTypedefs 儀Ѝ樒封code>rgb16_image_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);
//
ʹӃ核抓ͼ⎊ˣ稒ꇳ˼CЏͬ載춈. 㲿疵ċ㷨漻Ἤ⩍쏱ʓͼʇ籊DZά遠靚 ˹ν儒뎬遠ʓͼ, ָ儊Ǎ쏱ʽuӐ̮㤮 뻾仰˵, ȧ黊Ӎ쵄x_iterator쓵큋һ億鎲ᖱ퓵ėꈫςһ, ćoբ越Ӎ쾍ʇ1ά遠儮 ȧ黊Ӎ슇һά遠靚 ćoˣ稿ͻኹӃһ趵咻儑, ԋḼ쓵ē綆籔⋣稿ͻᔚY罏⑭뷄ڲ̗Xѭ뷮
һࣕˣ稻ᰑ餗瘓趔Ӧ儓TLˣ糯 =ȧ
m͢, Ӑʱ겻ᶔSTLˣ稌ṩ֘Ԙ. =ȧ,ի累lanar弴ꆷ巔a
բѹ儽ṻʇ, 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ף
concept ImageConcept<RandomAccess2DImageConcept Img> {
where MutableImageViewConcept<view_t>;
typename coord_t = view_t::coord_t;
};
ӫ樎놷ꍍ쏱ʓͼ⻍쬍쏱uӐ'mutable'腄ҲΪimmutable傻쏱⻊ǺܓIp> Ϡ阸ń/b>
ģЍ:
GIL ̡驁ˀ࠼code>image, ˼Ҕ value type (ϱ˘) ΪģॲΊ⇒oף
template <typename Pixel, \\ PixelValueConcept億㐍 bool IsPlanar, \\ planar 법ߠinterleaved 傻쏱 typename A=std::allocator<unsigned char> > class image;
ͼϱ鷫솷Ӑһ趶Ԇ벎ʽ, բԊ鷫엖攆뻲՟ז횶Ԇ뵄ͼϱ. 攆뵄奎늇ז횬 Ĭȏ攜Ԇ벎ʽʇ0, բҢζׅy儊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
GIL 儠variant ꍠ
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儠 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 巔a
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ʇ
// ʹӃģॻͼʵϖ 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᠒늱줺͖䐐΄쾴㐡儅╍. 㽁˕Ϟֆ,
12. 岸뵄Ԫꯊ Typedefsi뮐ԊǓ꼛儮 GIL儀Ѝܷdz㵄㤬đҔԄ恮 ΪK敢趎ʌ⬠GIL̡驁˴ypedefs,ָϲ᪗쵄ͼϱ, ϱ˘弴ꆷ,ϱ˘樎놷,ϱ˘ҽӃꍏዘֵ.˼C儃샻ױѭςa億㊽:ColorSpace + BitDepth + ["s|f"] + ["c"] + ["_planar"] + ["_step"] + ClassType + "_t"
Ԛբ/, ColorSpace ҲָʾҪ˘儴ΐ⬠=ȧ
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; };
բ/儠 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億㐍 };
ģԌ滻һʴ,⢊鈴 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] +
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>
ģ⢲됨Ҫಗ˹Ӑբꯊ,◰ģҪ儼俉.բ/ʇһի擽PEG I/O俊PI (ʹӃ
// 僵햸樂羶儊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 = ...; };
ȧ黊鈴毌썼ϱ)չ, ȷᣰ캬΄쾠
// 䲿ꖸ樵Ċ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 ꍠ
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綹Ϡ ʹӃಈ뻺㥇貼쏱ア䠼/a>왶莒CҪʹӃ栺˶ԍ쏱䦀儀鳤ʇ2K+1 x 2K+1 ϱ˘, բѹΒC蒪Ԛͼϱ儱߽帔趏ዘ儌, ςaʇ˼儊取:
template <typename SrcView, // ImageViewConcept億㐍 (Դʓͼ) typename DstImage> // ImageConcept億㐍(絻صč쏱) void create_with_margin(const SrcView& src, int k, DstImage& result) { gil_function_requires<ImageViewConcept<SrcView> >(); gil_function_requires<ImageConcept<DstImage> >(); gil_function_requires<ViewsCompatibleConcept<SrcView, typename DstImage::view_t> >(); result=DstImage(src.width()+2*k, src.height()+2*k); typename DstImage::view_t centerImg=subimage_view(view(result), k,k,src.width(),src.height()); std::copy(src.begin(), src.end(), centerImg.begin()); }
ΒC䴽蒻躉촳ά戟č쏱, Ȼ곎҃NJ鈴
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())); }
(עҢ擭 ֹ״ͼֹ״ͼͨ齼Ƌヿ趏ዘֵ㶏ֵĴΊ彮 ς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]; }
ʹӃ
template <typename GrayView, typename R> void grayimage_histogram(const GrayView& v, R& hist) { for_each_pixel(v, ++var(hist)[_1]); }
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); բͼϱ儽ṻʇ:
עҢ錄 uӐϱ˘兒,˹Ӑ儹䗷漊鼓Ԛ
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 ͼϱ
ȧ黃㏫樒嗔캵č貲 Ѝ, ģҪΪ˼̡驀Ѝ ֘Ԙѕɫ᤻뼯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; } };
ͨ齵瓃ͼϱʓͼ儳ɔắʽ
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()); } };
곎҃ǵĺ
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ҽӃ,淨罷芇:
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; };
嚶֘Ҫ載ʌ⊇ҪΪ 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趉輆Ŀ᪺
Generated on Thu Nov 8 21:53:19 2007 for Generic Image Library by 1.4.4
|