Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEBMP_COLORMISC_HXX
21 : #define INCLUDED_BASEBMP_COLORMISC_HXX
22 :
23 : #include <osl/diagnose.h>
24 : #include <basebmp/color.hxx>
25 : #include <basebmp/colortraits.hxx>
26 : #include <basebmp/accessortraits.hxx>
27 : #include <vigra/mathutil.hxx>
28 :
29 : // Contents of this header moved out of color.hxx, as it is not useful
30 : // for the general public (drags in vigra and other template
31 : // functionality, that shouldn't be necessary for the ordinary client
32 : // of BitmapDevice etc.)
33 :
34 : namespace basebmp
35 : {
36 :
37 : template< bool polarity > struct ColorBitmaskOutputMaskFunctor;
38 : template<> struct ColorBitmaskOutputMaskFunctor<true> : MaskFunctorBase<Color,sal_uInt8>
39 : {
40 : Color operator()( Color v1, sal_uInt8 m, Color v2 ) const
41 : {
42 : OSL_ASSERT(m<=1);
43 :
44 : return Color(v1.toInt32()*(sal_uInt8)(1-m) + v2.toInt32()*m);
45 : }
46 : };
47 : template<> struct ColorBitmaskOutputMaskFunctor<false> : MaskFunctorBase<Color,sal_uInt8>
48 : {
49 272 : Color operator()( Color v1, sal_uInt8 m, Color v2 ) const
50 : {
51 : OSL_ASSERT(m<=1);
52 :
53 272 : return Color(v1.toInt32()*m + v2.toInt32()*(sal_uInt8)(1-m));
54 : }
55 : };
56 :
57 : /// Specialized output mask functor for Color value type
58 : template<bool polarity> struct outputMaskFunctorSelector< Color, sal_uInt8, polarity, FastMask >
59 : {
60 : typedef ColorBitmaskOutputMaskFunctor<polarity> type;
61 : };
62 :
63 : template< bool polarity > struct ColorBlendFunctor8
64 : : public TernaryFunctorBase<sal_uInt8,Color,Color,Color>
65 : {
66 110748192 : Color operator()( sal_uInt8 alpha,
67 : Color v1,
68 : Color v2 ) const
69 : {
70 110748192 : alpha = polarity ? alpha : 255 - alpha;
71 :
72 110748192 : const sal_uInt8 v1_red( v1.getRed() );
73 110748192 : const sal_uInt8 v1_green( v1.getGreen() );
74 110748192 : const sal_uInt8 v1_blue( v1.getBlue() );
75 :
76 : // using '>> 8' instead of '/ 0x100' is ill-advised (shifted
77 : // value might be negative). Better rely on decent optimizer
78 : // here...
79 110748192 : return Color(((((sal_Int32)v2.getRed() - v1_red)*alpha) / 0x100) + v1_red,
80 110748192 : ((((sal_Int32)v2.getGreen() - v1_green)*alpha) / 0x100) + v1_green,
81 332244576 : ((((sal_Int32)v2.getBlue() - v1_blue)*alpha) / 0x100) + v1_blue);
82 : }
83 : };
84 :
85 : template< bool polarity > struct ColorBlendFunctor32
86 : : public TernaryFunctorBase<Color,Color,Color,Color>
87 : {
88 96826 : Color operator()( Color input,
89 : Color v1,
90 : Color v2 ) const
91 : {
92 96826 : sal_uInt8 alpha = input.getGreyscale();
93 96826 : alpha = polarity ? alpha : 255 - alpha;
94 :
95 96826 : const sal_uInt8 v1_red( v1.getRed() );
96 96826 : const sal_uInt8 v1_green( v1.getGreen() );
97 96826 : const sal_uInt8 v1_blue( v1.getBlue() );
98 :
99 : // using '>> 8' instead of '/ 0x100' is ill-advised (shifted
100 : // value might be negative). Better rely on decent optimizer
101 : // here...
102 96826 : return Color(((((sal_Int32)v2.getRed() - v1_red)*alpha) / 0x100) + v1_red,
103 96826 : ((((sal_Int32)v2.getGreen() - v1_green)*alpha) / 0x100) + v1_green,
104 290478 : ((((sal_Int32)v2.getBlue() - v1_blue)*alpha) / 0x100) + v1_blue);
105 : }
106 : };
107 :
108 :
109 :
110 : template<> struct ColorTraits< Color >
111 : {
112 : /// @return number of color channels
113 : static int numChannels() { return 3; }
114 :
115 : /// Type of a color component (i.e. the type of an individual channel)
116 : typedef sal_uInt8 component_type;
117 :
118 : /// Metafunction to select blend functor from color and alpha type
119 : template< typename AlphaType, bool polarity > struct blend_functor;
120 :
121 : /// Calculate normalized distance between color c1 and c2
122 668 : static inline double distance( const Color& c1,
123 : const Color& c2 )
124 : {
125 668 : return (c1 - c2).magnitude();
126 : }
127 :
128 60494 : static inline component_type toGreyscale( const Color& c )
129 : {
130 60494 : return c.getGreyscale();
131 : }
132 :
133 3 : static inline Color fromGreyscale( component_type c )
134 : {
135 3 : return Color(c,c,c);
136 : }
137 : };
138 :
139 : /// The version for plain 8 bit alpha
140 : template<bool polarity> struct ColorTraits< Color >::blend_functor< sal_uInt8, polarity >
141 : {
142 : typedef ColorBlendFunctor8<polarity> type;
143 : };
144 :
145 : /// The version taking grey value of a Color
146 : template<bool polarity> struct ColorTraits< Color >::blend_functor< Color, polarity >
147 : {
148 : typedef ColorBlendFunctor32<polarity> type;
149 : };
150 :
151 : } // namespace basebmp
152 :
153 : namespace vigra
154 : {
155 :
156 : template<>
157 : struct NumericTraits<basebmp::Color>
158 : {
159 : typedef basebmp::Color Type;
160 : typedef basebmp::Color Promote;
161 : typedef basebmp::Color RealPromote;
162 : typedef std::complex<basebmp::Color> ComplexPromote;
163 : typedef sal_uInt8 ValueType;
164 :
165 : typedef VigraTrueType isIntegral;
166 : typedef VigraFalseType isScalar;
167 : typedef VigraTrueType isSigned;
168 : typedef VigraTrueType isOrdered;
169 : typedef VigraFalseType isComplex;
170 :
171 : static Type zero() { return Type(); }
172 : static Type one() { return Type(0x01010101); }
173 : static Type nonZero() { return Type(0x01010101); }
174 :
175 : static Promote toPromote(const Type& v) { return v; }
176 : static RealPromote toRealPromote(const Type& v) { return v; }
177 : static Type fromPromote(const Promote& v) { return v; }
178 : static Type fromRealPromote(const RealPromote& v) { return v; }
179 : };
180 :
181 : } // namespace vigra
182 :
183 : #endif /* INCLUDED_BASEBMP_COLORMISC_HXX */
184 :
185 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|