1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_BASEBMP_COLORTRAITS_HXX
25 #define INCLUDED_BASEBMP_COLORTRAITS_HXX
26 
27 #include <basebmp/accessoradapters.hxx>
28 #include <basebmp/metafunctions.hxx>
29 
30 #include <vigra/mathutil.hxx>
31 
32 namespace basebmp
33 {
34 
35 /** Functor template, to calculate alpha blending between two
36     values. Float case.
37 
38     @tpl polarity
39     When true, 0 means fully transparent, and 1 fully opaque. And vice
40     versa.
41  */
42 template< typename ValueType,
43           typename AlphaType,
44           bool     polarity > struct BlendFunctor;
45 template< typename ValueType,
46           typename AlphaType > struct BlendFunctor<ValueType,AlphaType,true>
47   : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
48 {
operator ()basebmp::BlendFunctor49     ValueType operator()( AlphaType alpha,
50                           ValueType v1,
51                           ValueType v2 ) const
52     {
53         const typename vigra::NumericTraits<AlphaType>::RealPromote fAlpha(
54             vigra::NumericTraits<AlphaType>::toRealPromote(alpha));
55         return (vigra::NumericTraits<AlphaType>::one()-fAlpha)*v1 + fAlpha*v2;
56     }
57 };
58 template< typename ValueType,
59           typename AlphaType > struct BlendFunctor<ValueType,AlphaType,false>
60   : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
61 {
operator ()basebmp::BlendFunctor62     ValueType operator()( AlphaType alpha,
63                           ValueType v1,
64                           ValueType v2 ) const
65     {
66         const typename vigra::NumericTraits<AlphaType>::RealPromote fAlpha(
67             vigra::NumericTraits<AlphaType>::toRealPromote(alpha));
68         return fAlpha*v1 + (vigra::NumericTraits<AlphaType>::one()-fAlpha)*v2;
69     }
70 };
71 
72 /** Functor template, to calculate alpha blending between two
73     values. Integer case.
74 
75     @tpl polarity
76     When true, 0 means fully transparent, and 1 fully opaque. And vice
77     versa.
78  */
79 template< typename ValueType,
80           typename AlphaType,
81           bool     polarity > struct IntegerBlendFunctor;
82 template< typename ValueType,
83           typename AlphaType > struct IntegerBlendFunctor<ValueType,AlphaType,true>
84   : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
85 {
operator ()basebmp::IntegerBlendFunctor86     ValueType operator()( AlphaType alpha,
87                           ValueType v1,
88                           ValueType v2 ) const
89     {
90         return (vigra::NumericTraits<AlphaType>::toPromote(
91                     vigra::NumericTraits<AlphaType>::max()-alpha)*v1 + alpha*v2) /
92             vigra::NumericTraits<AlphaType>::max();
93     }
94 };
95 template< typename ValueType,
96           typename AlphaType > struct IntegerBlendFunctor<ValueType,AlphaType,false>
97   : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
98 {
operator ()basebmp::IntegerBlendFunctor99     ValueType operator()( AlphaType alpha,
100                           ValueType v1,
101                           ValueType v2 ) const
102     {
103         return (alpha*v1 +
104                 vigra::NumericTraits<AlphaType>::toPromote(
105                     vigra::NumericTraits<AlphaType>::max()-alpha)*v2) /
106             vigra::NumericTraits<AlphaType>::max();
107     }
108 };
109 
110 //-----------------------------------------------------------------------------
111 
112 template< typename ColorType > struct ColorTraits
113 {
114     /// Metafunction to select blend functor from color and alpha type
115     template< typename AlphaType, bool polarity > struct blend_functor : public
116         ifScalarIntegral< AlphaType,
117                           IntegerBlendFunctor< ColorType, AlphaType, polarity >,
118                           BlendFunctor< ColorType, AlphaType, polarity > > {};
119 
120     /// @return number of color channels
numChannelsbasebmp::ColorTraits121     static int numChannels() { return 1; }
122 
123     /// Type of a color component (i.e. the type of an individual channel)
124     typedef ColorType component_type;
125 
126     /// Calculate normalized distance between color c1 and c2
distancebasebmp::ColorTraits127     static inline vigra::NormTraits<ColorType> distance( ColorType c1,
128                                                          ColorType c2 )
129     {
130         return vigra::norm(c1 - c2);
131     }
132 
toGreyscalebasebmp::ColorTraits133     static inline component_type toGreyscale( ColorType c )
134     {
135         return c;
136     }
137 
fromGreyscalebasebmp::ColorTraits138     static inline ColorType fromGreyscale( component_type c )
139     {
140         return c;
141     }
142 };
143 
144 } // namespace basebmp
145 
146 #endif /* INCLUDED_BASEBMP_COLORTRAITS_HXX */
147