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 _BGFX_PIXEL_BPIXEL_HXX 25 #define _BGFX_PIXEL_BPIXEL_HXX 26 27 #include <sal/types.h> 28 #include <basegfx/numeric/ftools.hxx> 29 #include <basegfx/color/bcolor.hxx> 30 #include <basegfx/basegfxdllapi.h> 31 32 ////////////////////////////////////////////////////////////////////////////// 33 // predeclarations 34 35 ////////////////////////////////////////////////////////////////////////////// 36 37 namespace basegfx 38 { 39 class BASEGFX_DLLPUBLIC BPixel 40 { 41 protected: 42 union 43 { 44 struct 45 { 46 // bitfield 47 unsigned mnR : 8; // red intensity 48 unsigned mnG : 8; // green intensity 49 unsigned mnB : 8; // blue intensity 50 unsigned mnO : 8; // opacity, 0 == full transparence 51 } maRGBO; 52 53 struct 54 { 55 // bitfield 56 unsigned mnValue : 32; // all values 57 } maCombinedRGBO; 58 } maPixelUnion; 59 60 public: BPixel()61 BPixel() 62 { 63 maPixelUnion.maCombinedRGBO.mnValue = 0L; 64 } 65 66 // use explicit here to make sure everyone knows what he is doing. Values range from 67 // 0..255 integer here. BPixel(sal_uInt8 nRed,sal_uInt8 nGreen,sal_uInt8 nBlue,sal_uInt8 nOpacity)68 explicit BPixel(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue, sal_uInt8 nOpacity) 69 { 70 maPixelUnion.maRGBO.mnR = nRed; 71 maPixelUnion.maRGBO.mnG = nGreen; 72 maPixelUnion.maRGBO.mnB = nBlue; 73 maPixelUnion.maRGBO.mnO = nOpacity; 74 } 75 76 // constructor from BColor which uses double precision color, so change it 77 // to local integer format. It will also be clamped here. BPixel(const BColor & rColor,sal_uInt8 nOpacity)78 BPixel(const BColor& rColor, sal_uInt8 nOpacity) 79 { 80 maPixelUnion.maRGBO.mnR = sal_uInt8((rColor.getRed() * 255.0) + 0.5); 81 maPixelUnion.maRGBO.mnG = sal_uInt8((rColor.getGreen() * 255.0) + 0.5); 82 maPixelUnion.maRGBO.mnB = sal_uInt8((rColor.getBlue() * 255.0) + 0.5); 83 maPixelUnion.maRGBO.mnO = nOpacity; 84 } 85 86 // copy constructor BPixel(const BPixel & rPixel)87 BPixel(const BPixel& rPixel) 88 { 89 maPixelUnion.maCombinedRGBO.mnValue = rPixel.maPixelUnion.maCombinedRGBO.mnValue; 90 } 91 ~BPixel()92 ~BPixel() 93 {} 94 95 // assignment operator operator =(const BPixel & rPixel)96 BPixel& operator=( const BPixel& rPixel ) 97 { 98 maPixelUnion.maCombinedRGBO.mnValue = rPixel.maPixelUnion.maCombinedRGBO.mnValue; 99 return *this; 100 } 101 102 // data access read getRed() const103 sal_uInt8 getRed() const { return maPixelUnion.maRGBO.mnR; } getGreen() const104 sal_uInt8 getGreen() const { return maPixelUnion.maRGBO.mnG; } getBlue() const105 sal_uInt8 getBlue() const { return maPixelUnion.maRGBO.mnB; } getOpacity() const106 sal_uInt8 getOpacity() const { return maPixelUnion.maRGBO.mnO; } getRedGreenBlueOpacity() const107 sal_uInt32 getRedGreenBlueOpacity() const { return maPixelUnion.maCombinedRGBO.mnValue; } 108 109 // data access write setRed(sal_uInt8 nNew)110 void setRed(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnR = nNew; } setGreen(sal_uInt8 nNew)111 void setGreen(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnG = nNew; } setBlue(sal_uInt8 nNew)112 void setBlue(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnB = nNew; } setOpacity(sal_uInt8 nNew)113 void setOpacity(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnO = nNew; } setRedGreenBlueOpacity(sal_uInt32 nRedGreenBlueOpacity)114 void setRedGreenBlueOpacity(sal_uInt32 nRedGreenBlueOpacity) { maPixelUnion.maCombinedRGBO.mnValue = nRedGreenBlueOpacity; } setRedGreenBlue(sal_uInt8 nR,sal_uInt8 nG,sal_uInt8 nB)115 void setRedGreenBlue(sal_uInt8 nR, sal_uInt8 nG, sal_uInt8 nB) { maPixelUnion.maRGBO.mnR = nR; maPixelUnion.maRGBO.mnG = nG; maPixelUnion.maRGBO.mnB = nB; } 116 117 // comparators isInvisible() const118 bool isInvisible() const { return (0 == maPixelUnion.maRGBO.mnO); } isVisible() const119 bool isVisible() const { return (0 != maPixelUnion.maRGBO.mnO); } isEmpty() const120 bool isEmpty() const { return isInvisible(); } isUsed() const121 bool isUsed() const { return isVisible(); } 122 operator ==(const BPixel & rPixel) const123 bool operator==( const BPixel& rPixel ) const 124 { 125 return (rPixel.maPixelUnion.maCombinedRGBO.mnValue == maPixelUnion.maCombinedRGBO.mnValue); 126 } 127 operator !=(const BPixel & rPixel) const128 bool operator!=( const BPixel& rPixel ) const 129 { 130 return (rPixel.maPixelUnion.maCombinedRGBO.mnValue != maPixelUnion.maCombinedRGBO.mnValue); 131 } 132 133 // empty element 134 static const BPixel& getEmptyBPixel(); 135 }; 136 137 ////////////////////////////////////////////////////////////////////////// 138 // external operators 139 minimum(const BPixel & rTupA,const BPixel & rTupB)140 inline BPixel minimum(const BPixel& rTupA, const BPixel& rTupB) 141 { 142 return BPixel( 143 std::min(rTupB.getRed(), rTupA.getRed()), 144 std::min(rTupB.getGreen(), rTupA.getGreen()), 145 std::min(rTupB.getBlue(), rTupA.getBlue()), 146 std::min(rTupB.getOpacity(), rTupA.getOpacity())); 147 } 148 maximum(const BPixel & rTupA,const BPixel & rTupB)149 inline BPixel maximum(const BPixel& rTupA, const BPixel& rTupB) 150 { 151 return BPixel( 152 std::max(rTupB.getRed(), rTupA.getRed()), 153 std::max(rTupB.getGreen(), rTupA.getGreen()), 154 std::max(rTupB.getBlue(), rTupA.getBlue()), 155 std::max(rTupB.getOpacity(), rTupA.getOpacity())); 156 } 157 interpolate(const BPixel & rOld1,const BPixel & rOld2,double t)158 inline BPixel interpolate(const BPixel& rOld1, const BPixel& rOld2, double t) 159 { 160 if(rOld1 == rOld2) 161 { 162 return rOld1; 163 } 164 else if(0.0 >= t) 165 { 166 return rOld1; 167 } 168 else if(1.0 <= t) 169 { 170 return rOld2; 171 } 172 else 173 { 174 const sal_uInt32 nFactor(fround(256.0 * t)); 175 const sal_uInt32 nNegFac(256L - nFactor); 176 177 return BPixel( 178 (sal_uInt8)(((sal_uInt32)rOld1.getRed() * nNegFac + (sal_uInt32)rOld2.getRed() * nFactor) >> 8L), 179 (sal_uInt8)(((sal_uInt32)rOld1.getGreen() * nNegFac + (sal_uInt32)rOld2.getGreen() * nFactor) >> 8L), 180 (sal_uInt8)(((sal_uInt32)rOld1.getBlue() * nNegFac + (sal_uInt32)rOld2.getBlue() * nFactor) >> 8L), 181 (sal_uInt8)(((sal_uInt32)rOld1.getOpacity() * nNegFac + (sal_uInt32)rOld2.getOpacity() * nFactor) >> 8L)); 182 } 183 } 184 average(const BPixel & rOld1,const BPixel & rOld2)185 inline BPixel average(const BPixel& rOld1, const BPixel& rOld2) 186 { 187 return BPixel( 188 rOld1.getRed() == rOld2.getRed() ? rOld1.getRed() : (sal_uInt8)(((sal_uInt32)rOld1.getRed() + (sal_uInt32)rOld2.getRed()) >> 1L), 189 rOld1.getGreen() == rOld2.getGreen() ? rOld1.getGreen() : (sal_uInt8)(((sal_uInt32)rOld1.getGreen() + (sal_uInt32)rOld2.getGreen()) >> 1L), 190 rOld1.getBlue() == rOld2.getBlue() ? rOld1.getBlue() : (sal_uInt8)(((sal_uInt32)rOld1.getBlue() + (sal_uInt32)rOld2.getBlue()) >> 1L), 191 rOld1.getOpacity() == rOld2.getOpacity() ? rOld1.getOpacity() : (sal_uInt8)(((sal_uInt32)rOld1.getOpacity() + (sal_uInt32)rOld2.getOpacity()) >> 1L)); 192 } 193 average(const BPixel & rOld1,const BPixel & rOld2,const BPixel & rOld3)194 inline BPixel average(const BPixel& rOld1, const BPixel& rOld2, const BPixel& rOld3) 195 { 196 return BPixel( 197 (rOld1.getRed() == rOld2.getRed() && rOld2.getRed() == rOld3.getRed()) ? rOld1.getRed() : (sal_uInt8)(((sal_uInt32)rOld1.getRed() + (sal_uInt32)rOld2.getRed() + (sal_uInt32)rOld3.getRed()) / 3L), 198 (rOld1.getGreen() == rOld2.getGreen() && rOld2.getGreen() == rOld3.getGreen()) ? rOld1.getGreen() : (sal_uInt8)(((sal_uInt32)rOld1.getGreen() + (sal_uInt32)rOld2.getGreen() + (sal_uInt32)rOld3.getGreen()) / 3L), 199 (rOld1.getBlue() == rOld2.getBlue() && rOld2.getBlue() == rOld3.getBlue()) ? rOld1.getBlue() : (sal_uInt8)(((sal_uInt32)rOld1.getBlue() + (sal_uInt32)rOld2.getBlue() + (sal_uInt32)rOld3.getBlue()) / 3L), 200 (rOld1.getOpacity() == rOld2.getOpacity() && rOld2.getOpacity() == rOld3.getOpacity()) ? rOld1.getOpacity() : (sal_uInt8)(((sal_uInt32)rOld1.getOpacity() + (sal_uInt32)rOld2.getOpacity() + (sal_uInt32)rOld3.getOpacity()) / 3L)); 201 } 202 } // end of namespace basegfx 203 204 #endif /* _BGFX_PIXEL_BPIXEL_HXX */ 205