xref: /aoo4110/main/basebmp/inc/basebmp/colormisc.hxx (revision b1cdbd2c)
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_COLORMISC_HXX
25 #define INCLUDED_BASEBMP_COLORMISC_HXX
26 
27 #include <osl/diagnose.h>
28 #include <basebmp/color.hxx>
29 #include <basebmp/colortraits.hxx>
30 #include <basebmp/accessortraits.hxx>
31 #include <vigra/mathutil.hxx>
32 
33 // Contents of this header moved out of color.hxx, as it is not useful
34 // for the general public (drags in vigra and other template
35 // functionality, that shouldn't be necessary for the ordinary client
36 // of BitmapDevice etc.)
37 
38 namespace basebmp
39 {
40 
41 template< bool polarity > struct ColorBitmaskOutputMaskFunctor;
42 template<> struct ColorBitmaskOutputMaskFunctor<true> : MaskFunctorBase<Color,sal_uInt8>
43 {
operator ()basebmp::ColorBitmaskOutputMaskFunctor44     Color operator()( Color v1, sal_uInt8 m, Color v2 ) const
45     {
46         OSL_ASSERT(m<=1);
47 
48         return Color(v1.toInt32()*(sal_uInt8)(1-m) + v2.toInt32()*m);
49     }
50 };
51 template<> struct ColorBitmaskOutputMaskFunctor<false> : MaskFunctorBase<Color,sal_uInt8>
52 {
operator ()basebmp::ColorBitmaskOutputMaskFunctor53     Color operator()( Color v1, sal_uInt8 m, Color v2 ) const
54     {
55         OSL_ASSERT(m<=1);
56 
57         return Color(v1.toInt32()*m + v2.toInt32()*(sal_uInt8)(1-m));
58     }
59 };
60 
61 /// Specialized output mask functor for Color value type
62 template<bool polarity> struct outputMaskFunctorSelector< Color, sal_uInt8, polarity, FastMask >
63 {
64     typedef ColorBitmaskOutputMaskFunctor<polarity> type;
65 };
66 
67 template< bool polarity > struct ColorBlendFunctor8
68   : public TernaryFunctorBase<sal_uInt8,Color,Color,Color>
69 {
operator ()basebmp::ColorBlendFunctor870     Color operator()( sal_uInt8 alpha,
71                       Color     v1,
72                       Color     v2 ) const
73     {
74         alpha = polarity ? alpha : 255 - alpha;
75 
76         const sal_uInt8 v1_red( v1.getRed() );
77         const sal_uInt8 v1_green( v1.getGreen() );
78         const sal_uInt8 v1_blue( v1.getBlue() );
79 
80         // using '>> 8' instead of '/ 0x100' is ill-advised (shifted
81         // value might be negative). Better rely on decent optimizer
82         // here...
83         return Color(((((sal_Int32)v2.getRed() - v1_red)*alpha) / 0x100) + v1_red,
84                      ((((sal_Int32)v2.getGreen() - v1_green)*alpha) / 0x100) + v1_green,
85                      ((((sal_Int32)v2.getBlue() - v1_blue)*alpha) / 0x100) + v1_blue);
86     }
87 };
88 
89 template< bool polarity > struct ColorBlendFunctor32
90   : public TernaryFunctorBase<Color,Color,Color,Color>
91 {
operator ()basebmp::ColorBlendFunctor3292     Color operator()( Color input,
93                       Color v1,
94                       Color v2 ) const
95     {
96         sal_uInt8 alpha = input.getGreyscale();
97         alpha = polarity ? alpha : 255 - alpha;
98 
99         const sal_uInt8 v1_red( v1.getRed() );
100         const sal_uInt8 v1_green( v1.getGreen() );
101         const sal_uInt8 v1_blue( v1.getBlue() );
102 
103         // using '>> 8' instead of '/ 0x100' is ill-advised (shifted
104         // value might be negative). Better rely on decent optimizer
105         // here...
106         return Color(((((sal_Int32)v2.getRed() - v1_red)*alpha) / 0x100) + v1_red,
107                      ((((sal_Int32)v2.getGreen() - v1_green)*alpha) / 0x100) + v1_green,
108                      ((((sal_Int32)v2.getBlue() - v1_blue)*alpha) / 0x100) + v1_blue);
109     }
110 };
111 
112 //-----------------------------------------------------------------------------
113 
114 template<> struct ColorTraits< Color >
115 {
116     /// @return number of color channels
numChannelsbasebmp::ColorTraits117     static int numChannels() { return 3; }
118 
119     /// Type of a color component (i.e. the type of an individual channel)
120     typedef sal_uInt8 component_type;
121 
122     /// Metafunction to select blend functor from color and alpha type
123     template< typename AlphaType, bool polarity > struct blend_functor;
124 
125     /// Calculate normalized distance between color c1 and c2
distancebasebmp::ColorTraits126     static inline double distance( const Color& c1,
127                                    const Color& c2 )
128     {
129         return (c1 - c2).magnitude();
130     }
131 
toGreyscalebasebmp::ColorTraits132     static inline component_type toGreyscale( const Color& c )
133     {
134         return c.getGreyscale();
135     }
136 
fromGreyscalebasebmp::ColorTraits137     static inline Color fromGreyscale( component_type c )
138     {
139         return Color(c,c,c);
140     }
141 };
142 
143 /// The version for plain 8 bit alpha
144 template<bool polarity> struct ColorTraits< Color >::blend_functor< sal_uInt8, polarity >
145 {
146     typedef ColorBlendFunctor8<polarity> type;
147 };
148 
149 /// The version taking grey value of a Color
150 template<bool polarity> struct ColorTraits< Color >::blend_functor< Color, polarity >
151 {
152     typedef ColorBlendFunctor32<polarity> type;
153 };
154 
155 } // namespace basebmp
156 
157 namespace vigra
158 {
159 
160 template<>
161 struct NumericTraits<basebmp::Color>
162 {
163     typedef basebmp::Color Type;
164     typedef basebmp::Color Promote;
165     typedef basebmp::Color RealPromote;
166     typedef std::complex<basebmp::Color> ComplexPromote;
167     typedef sal_uInt8 ValueType;
168 
169     typedef VigraTrueType  isIntegral;
170     typedef VigraFalseType isScalar;
171     typedef VigraTrueType  isSigned;
172     typedef VigraTrueType  isOrdered;
173     typedef VigraFalseType isComplex;
174 
zerovigra::NumericTraits175     static Type zero() { return Type(); }
onevigra::NumericTraits176     static Type one() { return Type(0x01010101); }
nonZerovigra::NumericTraits177     static Type nonZero() { return Type(0x01010101); }
178 
toPromotevigra::NumericTraits179     static Promote toPromote(const Type& v) { return v; }
toRealPromotevigra::NumericTraits180     static RealPromote toRealPromote(const Type& v) { return v; }
fromPromotevigra::NumericTraits181     static Type fromPromote(const Promote& v) { return v; }
fromRealPromotevigra::NumericTraits182     static Type fromRealPromote(const RealPromote& v) { return v; }
183 };
184 
185 } // namespace vigra
186 
187 #endif /* INCLUDED_BASEBMP_COLORMISC_HXX */
188