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