Boost GIL


color_base_algorithm.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3 
4  Use, modification and distribution are subject to the Boost Software License,
5  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6  http://www.boost.org/LICENSE_1_0.txt).
7 
8  See http://opensource.adobe.com/gil for most recent version including documentation.
9 */
10 
11 /*************************************************************************************************/
12 
13 #ifndef GIL_COLOR_BASE_ALGORITHM_HPP
14 #define GIL_COLOR_BASE_ALGORITHM_HPP
15 
24 
25 #include <algorithm>
26 
27 #include <boost/config.hpp>
28 #include <boost/type_traits.hpp>
29 #include <boost/utility/enable_if.hpp>
30 #include <boost/mpl/contains.hpp>
31 #include <boost/mpl/at.hpp>
32 
33 #include "gil_config.hpp"
34 #include "gil_concept.hpp"
35 #include "utilities.hpp"
36 
37 namespace boost { namespace gil {
38 
39 
45 
58 template <typename ColorBase>
61 struct size : public mpl::size<typename ColorBase::layout_t::color_space_t> {};
62 
68 
95 template <typename ColorBase, int K> struct kth_semantic_element_type {
98  BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
99  typedef typename kth_element_type<ColorBase, semantic_index>::type type;
100 };
101 
104 template <typename ColorBase, int K> struct kth_semantic_element_reference_type {
105  BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
106  typedef typename kth_element_reference_type<ColorBase,semantic_index>::type type;
107  static type get(ColorBase& cb) { return gil::at_c<semantic_index>(cb); }
108 };
109 
112 template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type {
113  BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
114  typedef typename kth_element_const_reference_type<ColorBase,semantic_index>::type type;
115  static type get(const ColorBase& cb) { return gil::at_c<semantic_index>(cb); }
116 };
117 
120 template <int K, typename ColorBase> inline
121 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type
122 semantic_at_c(ColorBase& p) {
124 }
125 
128 template <int K, typename ColorBase> inline
129 typename kth_semantic_element_const_reference_type<ColorBase,K>::type
130 semantic_at_c(const ColorBase& p) {
132 }
133 
139 
159 template <typename ColorBase, typename Color>
162 struct contains_color : public mpl::contains<typename ColorBase::layout_t::color_space_t,Color> {};
163 
164 template <typename ColorBase, typename Color>
165 struct color_index_type : public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
166 
169 template <typename ColorBase, typename Color>
170 struct color_element_type : public kth_semantic_element_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
171 
174 template <typename ColorBase, typename Color>
175 struct color_element_reference_type : public kth_semantic_element_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
176 
179 template <typename ColorBase, typename Color>
180 struct color_element_const_reference_type : public kth_semantic_element_const_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
181 
184 template <typename ColorBase, typename Color>
185 typename color_element_reference_type<ColorBase,Color>::type get_color(ColorBase& cb, Color=Color()) {
187 }
188 
191 template <typename ColorBase, typename Color>
192 typename color_element_const_reference_type<ColorBase,Color>::type get_color(const ColorBase& cb, Color=Color()) {
194 }
195 
201 
213 template <typename ColorBase>
216 struct element_type : public kth_element_type<ColorBase, 0> {};
217 
220 template <typename ColorBase>
221 struct element_reference_type : public kth_element_reference_type<ColorBase, 0> {};
222 
225 template <typename ColorBase>
226 struct element_const_reference_type : public kth_element_const_reference_type<ColorBase, 0> {};
227 
228 
229 namespace detail {
230 
231 // compile-time recursion for per-element operations on color bases
232 template <int N>
233 struct element_recursion {
234  //static_equal
235  template <typename P1,typename P2>
236  static bool static_equal(const P1& p1, const P2& p2) {
237  return element_recursion<N-1>::static_equal(p1,p2) &&
238  semantic_at_c<N-1>(p1)==semantic_at_c<N-1>(p2);
239  }
240  //static_copy
241  template <typename P1,typename P2>
242  static void static_copy(const P1& p1, P2& p2) {
243  element_recursion<N-1>::static_copy(p1,p2);
244  semantic_at_c<N-1>(p2)=semantic_at_c<N-1>(p1);
245  }
246  //static_fill
247  template <typename P,typename T2>
248  static void static_fill(P& p, T2 v) {
249  element_recursion<N-1>::static_fill(p,v);
250  semantic_at_c<N-1>(p)=v;
251  }
252  //static_generate
253  template <typename Dst,typename Op>
254  static void static_generate(Dst& dst, Op op) {
255  element_recursion<N-1>::static_generate(dst,op);
256  semantic_at_c<N-1>(dst)=op();
257  }
258  //static_for_each with one source
259  template <typename P1,typename Op>
260  static Op static_for_each(P1& p1, Op op) {
261  Op op2(element_recursion<N-1>::static_for_each(p1,op));
262  op2(semantic_at_c<N-1>(p1));
263  return op2;
264  }
265  template <typename P1,typename Op>
266  static Op static_for_each(const P1& p1, Op op) {
267  Op op2(element_recursion<N-1>::static_for_each(p1,op));
268  op2(semantic_at_c<N-1>(p1));
269  return op2;
270  }
271  //static_for_each with two sources
272  template <typename P1,typename P2,typename Op>
273  static Op static_for_each(P1& p1, P2& p2, Op op) {
274  Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
275  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
276  return op2;
277  }
278  template <typename P1,typename P2,typename Op>
279  static Op static_for_each(P1& p1, const P2& p2, Op op) {
280  Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
281  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
282  return op2;
283  }
284  template <typename P1,typename P2,typename Op>
285  static Op static_for_each(const P1& p1, P2& p2, Op op) {
286  Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
287  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
288  return op2;
289  }
290  template <typename P1,typename P2,typename Op>
291  static Op static_for_each(const P1& p1, const P2& p2, Op op) {
292  Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
293  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
294  return op2;
295  }
296  //static_for_each with three sources
297  template <typename P1,typename P2,typename P3,typename Op>
298  static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
299  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
300  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
301  return op2;
302  }
303  template <typename P1,typename P2,typename P3,typename Op>
304  static Op static_for_each(P1& p1, P2& p2, const P3& p3, Op op) {
305  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
306  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
307  return op2;
308  }
309  template <typename P1,typename P2,typename P3,typename Op>
310  static Op static_for_each(P1& p1, const P2& p2, P3& p3, Op op) {
311  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
312  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
313  return op2;
314  }
315  template <typename P1,typename P2,typename P3,typename Op>
316  static Op static_for_each(P1& p1, const P2& p2, const P3& p3, Op op) {
317  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
318  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
319  return op2;
320  }
321  template <typename P1,typename P2,typename P3,typename Op>
322  static Op static_for_each(const P1& p1, P2& p2, P3& p3, Op op) {
323  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
324  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
325  return op2;
326  }
327  template <typename P1,typename P2,typename P3,typename Op>
328  static Op static_for_each(const P1& p1, P2& p2, const P3& p3, Op op) {
329  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
330  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
331  return op2;
332  }
333  template <typename P1,typename P2,typename P3,typename Op>
334  static Op static_for_each(const P1& p1, const P2& p2, P3& p3, Op op) {
335  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
336  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
337  return op2;
338  }
339  template <typename P1,typename P2,typename P3,typename Op>
340  static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, Op op) {
341  Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
342  op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
343  return op2;
344  }
345  //static_transform with one source
346  template <typename P1,typename Dst,typename Op>
347  static Op static_transform(P1& src, Dst& dst, Op op) {
348  Op op2(element_recursion<N-1>::static_transform(src,dst,op));
349  semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
350  return op2;
351  }
352  template <typename P1,typename Dst,typename Op>
353  static Op static_transform(const P1& src, Dst& dst, Op op) {
354  Op op2(element_recursion<N-1>::static_transform(src,dst,op));
355  semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
356  return op2;
357  }
358  //static_transform with two sources
359  template <typename P1,typename P2,typename Dst,typename Op>
360  static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
361  Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
362  semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
363  return op2;
364  }
365  template <typename P1,typename P2,typename Dst,typename Op>
366  static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) {
367  Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
368  semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
369  return op2;
370  }
371  template <typename P1,typename P2,typename Dst,typename Op>
372  static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) {
373  Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
374  semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
375  return op2;
376  }
377  template <typename P1,typename P2,typename Dst,typename Op>
378  static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) {
379  Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
380  semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
381  return op2;
382  }
383 };
384 
385 // Termination condition of the compile-time recursion for element operations on a color base
386 template<> struct element_recursion<0> {
387  //static_equal
388  template <typename P1,typename P2>
389  static bool static_equal(const P1&, const P2&) { return true; }
390  //static_copy
391  template <typename P1,typename P2>
392  static void static_copy(const P1&, const P2&) {}
393  //static_fill
394  template <typename P, typename T2>
395  static void static_fill(const P&, T2) {}
396  //static_generate
397  template <typename Dst,typename Op>
398  static void static_generate(const Dst&,Op){}
399  //static_for_each with one source
400  template <typename P1,typename Op>
401  static Op static_for_each(const P1&,Op op){return op;}
402  //static_for_each with two sources
403  template <typename P1,typename P2,typename Op>
404  static Op static_for_each(const P1&,const P2&,Op op){return op;}
405  //static_for_each with three sources
406  template <typename P1,typename P2,typename P3,typename Op>
407  static Op static_for_each(const P1&,const P2&,const P3&,Op op){return op;}
408  //static_transform with one source
409  template <typename P1,typename Dst,typename Op>
410  static Op static_transform(const P1&,const Dst&,Op op){return op;}
411  //static_transform with two sources
412  template <typename P1,typename P2,typename Dst,typename Op>
413  static Op static_transform(const P1&,const P2&,const Dst&,Op op){return op;}
414 };
415 
416 // std::min and std::max don't have the mutable overloads...
417 template <typename Q> inline const Q& mutable_min(const Q& x, const Q& y) { return x<y ? x : y; }
418 template <typename Q> inline Q& mutable_min( Q& x, Q& y) { return x<y ? x : y; }
419 template <typename Q> inline const Q& mutable_max(const Q& x, const Q& y) { return x<y ? y : x; }
420 template <typename Q> inline Q& mutable_max( Q& x, Q& y) { return x<y ? y : x; }
421 
422 
423 // compile-time recursion for min/max element
424 template <int N>
425 struct min_max_recur {
426  template <typename P> static typename element_const_reference_type<P>::type max_(const P& p) {
427  return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
428  }
429  template <typename P> static typename element_reference_type<P>::type max_( P& p) {
430  return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
431  }
432  template <typename P> static typename element_const_reference_type<P>::type min_(const P& p) {
433  return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
434  }
435  template <typename P> static typename element_reference_type<P>::type min_( P& p) {
436  return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
437  }
438 };
439 
440 // termination condition of the compile-time recursion for min/max element
441 template <>
442 struct min_max_recur<1> {
443  template <typename P> static typename element_const_reference_type<P>::type max_(const P& p) { return semantic_at_c<0>(p); }
444  template <typename P> static typename element_reference_type<P>::type max_( P& p) { return semantic_at_c<0>(p); }
445  template <typename P> static typename element_const_reference_type<P>::type min_(const P& p) { return semantic_at_c<0>(p); }
446  template <typename P> static typename element_reference_type<P>::type min_( P& p) { return semantic_at_c<0>(p); }
447 };
448 } // namespace detail
449 
450 
466 template <typename P>
467 BOOST_FORCEINLINE
468 typename element_const_reference_type<P>::type static_max(const P& p) { return detail::min_max_recur<size<P>::value>::max_(p); }
469 
470 template <typename P>
471 BOOST_FORCEINLINE
472 typename element_reference_type<P>::type static_max( P& p) { return detail::min_max_recur<size<P>::value>::max_(p); }
473 
474 template <typename P>
475 BOOST_FORCEINLINE
476 typename element_const_reference_type<P>::type static_min(const P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
477 
478 template <typename P>
479 BOOST_FORCEINLINE
480 typename element_reference_type<P>::type static_min( P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
482 
500 template <typename P1,typename P2>
501 BOOST_FORCEINLINE
502 bool static_equal(const P1& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
503 
505 
523 template <typename Src,typename Dst>
524 BOOST_FORCEINLINE
525 void static_copy(const Src& src, Dst& dst) { detail::element_recursion<size<Dst>::value>::static_copy(src,dst); }
526 
528 
542 template <typename P,typename V>
543 BOOST_FORCEINLINE
544 void static_fill(P& p, const V& v) { detail::element_recursion<size<P>::value>::static_fill(p,v); }
546 
568 template <typename P1,typename Op>
569 BOOST_FORCEINLINE
570 void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
572 
601 //static_transform with one source
602 template <typename Src,typename Dst,typename Op>
603 BOOST_FORCEINLINE
604 Op static_transform(Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
605 template <typename Src,typename Dst,typename Op>
606 BOOST_FORCEINLINE
607 Op static_transform(const Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
608 //static_transform with two sources
609 template <typename P2,typename P3,typename Dst,typename Op>
610 BOOST_FORCEINLINE
611 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
612 template <typename P2,typename P3,typename Dst,typename Op>
613 BOOST_FORCEINLINE
614 Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
615 template <typename P2,typename P3,typename Dst,typename Op>
616 BOOST_FORCEINLINE
617 Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
618 template <typename P2,typename P3,typename Dst,typename Op>
619 BOOST_FORCEINLINE
620 Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
622 
650 //static_for_each with one source
651 template <typename P1,typename Op>
652 BOOST_FORCEINLINE
653 Op static_for_each( P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
654 template <typename P1,typename Op>
655 BOOST_FORCEINLINE
656 Op static_for_each(const P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
657 //static_for_each with two sources
658 template <typename P1,typename P2,typename Op>
659 BOOST_FORCEINLINE
660 Op static_for_each(P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
661 template <typename P1,typename P2,typename Op>
662 BOOST_FORCEINLINE
663 Op static_for_each(P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
664 template <typename P1,typename P2,typename Op>
665 BOOST_FORCEINLINE
666 Op static_for_each(const P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
667 template <typename P1,typename P2,typename Op>
668 BOOST_FORCEINLINE
669 Op static_for_each(const P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
670 //static_for_each with three sources
671 template <typename P1,typename P2,typename P3,typename Op>
672 BOOST_FORCEINLINE
673 Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
674 template <typename P1,typename P2,typename P3,typename Op>
675 BOOST_FORCEINLINE
676 Op static_for_each(P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
677 template <typename P1,typename P2,typename P3,typename Op>
678 BOOST_FORCEINLINE
679 Op static_for_each(P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
680 template <typename P1,typename P2,typename P3,typename Op>
681 BOOST_FORCEINLINE
682 Op static_for_each(P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
683 template <typename P1,typename P2,typename P3,typename Op>
684 BOOST_FORCEINLINE
685 Op static_for_each(const P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
686 template <typename P1,typename P2,typename P3,typename Op>
687 BOOST_FORCEINLINE
688 Op static_for_each(const P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
689 template <typename P1,typename P2,typename P3,typename Op>
690 BOOST_FORCEINLINE
691 Op static_for_each(const P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
692 template <typename P1,typename P2,typename P3,typename Op>
693 BOOST_FORCEINLINE
694 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
696 
697 } } // namespace boost::gil
698 
699 #endif
disable_if< is_const< ColorBase >, typename kth_semantic_element_reference_type< ColorBase, K >::type >::type semantic_at_c(ColorBase &p)
A mutable accessor to the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:122
Specifies the return type of the constant element accessor by color name, get_color(color_base, Color());.
Definition: color_base_algorithm.hpp:180
Specifies the element type of a homogeneous color base.
Definition: color_base_algorithm.hpp:216
Specifies the type of the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:97
Concept check classes for GIL concepts.
Specifies the return type of the mutable semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:104
A predicate metafunction determining whether a given color base contains a given color.
Definition: color_base_algorithm.hpp:162
Specifies the return type of the mutable element accessor at_c of a homogeneous color base...
Definition: color_base.hpp:50
Specifies the type of the element associated with a given color tag.
Definition: color_base_algorithm.hpp:170
Specifies the return type of the mutable element accessor by color name, get_color(color_base, Color());.
Definition: color_base_algorithm.hpp:175
GIL configuration file.
Returns an MPL integral type specifying the number of elements in a color base.
Definition: color_base_algorithm.hpp:61
Specifies the return type of the constant semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:112
Returns the index corresponding to the first occurrance of a given given type in. ...
Definition: utilities.hpp:307
color_element_const_reference_type< ColorBase, Color >::type get_color(const ColorBase &cb, Color=Color())
Constant accessor to the element associated with a given color name.
Definition: color_base_algorithm.hpp:192
Various utilities not specific to the image library. Some are non-standard STL extensions or generic ...