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