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_VCL_BITMAP_HXX 21 #define INCLUDED_VCL_BITMAP_HXX 22 23 #include <tools/solar.h> 24 #include <vcl/checksum.hxx> 25 #include <vcl/dllapi.h> 26 #include <vcl/mapmod.hxx> 27 #include <vcl/region.hxx> 28 #include <vcl/scopedbitmapaccess.hxx> 29 #include <o3tl/typed_flags_set.hxx> 30 #include <memory> 31 32 class Color; 33 34 template <typename Arg, typename Ret> class Link; 35 36 enum class BmpMirrorFlags 37 { 38 NONE = 0x00, 39 Horizontal = 0x01, 40 Vertical = 0x02, 41 }; 42 43 namespace o3tl 44 { 45 template<> struct typed_flags<BmpMirrorFlags> : is_typed_flags<BmpMirrorFlags, 0x03> {}; 46 } 47 48 enum class BmpScaleFlag 49 { 50 // Try to preferably use these. 51 Default, 52 Fast, 53 BestQuality, 54 // Specific algorithms, use only if you really need to (mainly used for tests) 55 NearestNeighbor, 56 Interpolate, // fast, integer bilinear 57 Lanczos, 58 BiCubic, 59 BiLinear, 60 Super // bilinear interpolation when supersampling and averaging when subsampling under certain scale 61 }; 62 63 #define BMP_COL_TRANS Color( 252, 3, 251 ) 64 65 enum class BmpConversion 66 { 67 NNONE, 68 N1BitThreshold, 69 N4BitGreys, 70 N4BitColors, 71 N8BitGreys, 72 N8BitColors, 73 N24Bit, 74 N32Bit, 75 N8BitTrans, 76 N8BitNoConversion // make 8bit without color conversion (e.g. take the red channel) 77 }; 78 79 enum class BmpCombine 80 { 81 Or, And 82 }; 83 84 class BitmapInfoAccess; 85 class BitmapReadAccess; 86 class BitmapWriteAccess; 87 class BitmapPalette; 88 class GDIMetaFile; 89 class AlphaMask; 90 class OutputDevice; 91 class SalBitmap; 92 93 struct BitmapSystemData 94 { 95 #if defined(_WIN32) 96 void* pDIB; // device independent byte buffer 97 #elif defined( MACOSX ) || defined( IOS ) 98 // Nothing needed, apparently 99 #else 100 void* aPixmap; 101 #endif 102 int mnWidth; 103 int mnHeight; 104 }; 105 106 class SAL_WARN_UNUSED VCL_DLLPUBLIC Bitmap 107 { 108 public: 109 110 Bitmap(); 111 Bitmap( const Bitmap& rBitmap ); 112 Bitmap( const Size& rSizePixel, sal_uInt16 nBitCount, const BitmapPalette* pPal = nullptr ); 113 explicit Bitmap( std::shared_ptr<SalBitmap> const & xSalBitmap ); 114 virtual ~Bitmap(); 115 116 Bitmap& operator=( const Bitmap& rBitmap ); 117 Bitmap& operator=( Bitmap&& rBitmap ) noexcept; 118 inline bool operator!() const; 119 bool operator==( const Bitmap& rBitmap ) const; 120 bool operator!=( const Bitmap& rBitmap ) const { return !operator==(rBitmap); } 121 122 inline bool IsEmpty() const; 123 void SetEmpty(); 124 125 inline const MapMode& GetPrefMapMode() const; 126 inline void SetPrefMapMode( const MapMode& rMapMode ); 127 128 inline const Size& GetPrefSize() const; 129 inline void SetPrefSize( const Size& rSize ); 130 131 Size GetSizePixel() const; 132 133 sal_uInt16 GetBitCount() const; 134 inline sal_Int64 GetColorCount() const; 135 inline sal_uLong GetSizeBytes() const; 136 bool HasGreyPalette() const; 137 /** get system dependent bitmap data 138 139 @param rData 140 The system dependent BitmapSystemData structure to be filled 141 142 @return true if the bitmap has a valid system object (e.g. not empty) 143 */ 144 bool GetSystemData( BitmapSystemData& rData ) const; 145 146 BitmapChecksum GetChecksum() const; 147 148 Bitmap CreateDisplayBitmap( OutputDevice* pDisplay ) const; 149 150 static const BitmapPalette& 151 GetGreyPalette( int nEntries ); 152 153 public: 154 155 /** Convert bitmap format 156 157 @param eConversion 158 The format this bitmap should be converted to. 159 160 @return true the conversion was completed successfully. 161 */ 162 bool Convert( BmpConversion eConversion ); 163 164 /** Apply a Floyd dither algorithm to the bitmap 165 166 This method dithers the bitmap inplace, i.e. a true color 167 bitmap is converted to a paletted bitmap, reducing the color 168 deviation by error diffusion. 169 170 */ 171 bool Dither(); 172 173 /** Crop the bitmap 174 175 @param rRectPixel 176 A rectangle specifying the crop amounts on all four sides of 177 the bitmap. If the upper left corner of the bitmap is assigned 178 (0,0), then this method cuts out the given rectangle from the 179 bitmap. Note that the rectangle is clipped to the bitmap's 180 dimension, i.e. negative left,top rectangle coordinates or 181 exceeding width or height is ignored. 182 183 @return true cropping was performed successfully. If 184 nothing had to be cropped, because e.g. the crop rectangle 185 included the bitmap, false is returned, too! 186 */ 187 bool Crop( const tools::Rectangle& rRectPixel ); 188 189 /** Expand the bitmap by pixel padding 190 191 @param nDX 192 Number of pixel to pad at the right border of the bitmap 193 194 @param nDY 195 Number of scanlines to pad at the bottom border of the bitmap 196 197 @param pInitColor 198 Color to use for padded pixel 199 200 @return true, if padding was performed successfully. false is 201 not only returned when the operation failed, but also if 202 nothing had to be done, e.g. because nDX and nDY were zero. 203 */ 204 bool Expand( 205 sal_uLong nDX, sal_uLong nDY, 206 const Color* pInitColor = nullptr ); 207 208 /** Copy a rectangular area from another bitmap 209 210 @param rRectDst 211 Destination rectangle in this bitmap. This is clipped to the 212 bitmap dimensions. 213 214 @param rRectSrc 215 Source rectangle in pBmpSrc. This is clipped to the source 216 bitmap dimensions. Note further that no scaling takes place 217 during this copy operation, i.e. only the minimum of source 218 and destination rectangle's width and height are used. 219 220 @param pBmpSrc 221 The source bitmap to copy from. If this argument is NULL, or 222 equal to the object this method is called on, copying takes 223 place within the same bitmap. 224 225 @return true, if the operation completed successfully. false 226 is not only returned when the operation failed, but also if 227 nothing had to be done, e.g. because one of the rectangles are 228 empty. 229 */ 230 bool CopyPixel( 231 const tools::Rectangle& rRectDst, 232 const tools::Rectangle& rRectSrc, 233 const Bitmap* pBmpSrc = nullptr ); 234 235 bool CopyPixel_AlphaOptimized( 236 const tools::Rectangle& rRectDst, 237 const tools::Rectangle& rRectSrc, 238 const Bitmap* pBmpSrc ); 239 240 /** Perform boolean operations with another bitmap 241 242 @param rMask 243 The mask bitmap in the selected combine operation 244 245 @param eCombine 246 The combine operation to perform on the bitmap 247 248 @return true, if the operation was completed successfully. 249 */ 250 bool CombineSimple( 251 const Bitmap& rMask, 252 BmpCombine eCombine ); 253 254 /** Alpha-blend the given bitmap against a specified uniform 255 background color. 256 257 @attention This method might convert paletted bitmaps to 258 truecolor, to be able to represent every necessary color. Note 259 that during alpha blending, lots of colors not originally 260 included in the bitmap can be generated. 261 262 @param rAlpha 263 Alpha mask to blend with 264 265 @param rBackgroundColor 266 Background color to use for every pixel during alpha blending 267 268 @return true, if blending was successful, false otherwise 269 */ 270 bool Blend( 271 const AlphaMask& rAlpha, 272 const Color& rBackgroundColor ); 273 274 /** Fill the entire bitmap with the given color 275 276 @param rFillColor 277 Color value to use for filling 278 279 @return true, if the operation was completed successfully. 280 */ 281 bool Erase( const Color& rFillColor ); 282 283 /** Perform the Invert operation on every pixel 284 285 @return true, if the operation was completed successfully. 286 */ 287 bool Invert(); 288 289 /** Mirror the bitmap 290 291 @param nMirrorFlags 292 About which axis (horizontal, vertical, or both) to mirror 293 294 @return true, if the operation was completed successfully. 295 */ 296 bool Mirror( BmpMirrorFlags nMirrorFlags ); 297 298 /** Scale the bitmap 299 300 @param rNewSize 301 The resulting size of the scaled bitmap 302 303 @param nScaleFlag 304 The algorithm to be used for scaling 305 306 @return true, if the operation was completed successfully. 307 */ 308 bool Scale( const Size& rNewSize, BmpScaleFlag nScaleFlag = BmpScaleFlag::Default ); 309 310 /** Scale the bitmap 311 312 @param rScaleX 313 The scale factor in x direction. 314 315 @param rScaleY 316 The scale factor in y direction. 317 318 @param nScaleFlag 319 Method of scaling - it is recommended that either BmpScaleFlag::Default or BmpScaleFlag::BestQuality be used. 320 321 @return true, if the operation was completed successfully. 322 */ 323 bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag = BmpScaleFlag::Default ); 324 325 /** 326 Returns true if bitmap scaling is considered to be fast. 327 328 Currently this returns true if OpenGL is used for scaling, otherwise false (CPU scaling is slower). 329 330 @since 4.5 331 */ 332 static bool HasFastScale(); 333 334 // Adapt the BitCount of rNew to BitCount of total, including grey or color palette 335 // Can be used to create alpha/mask bitmaps after their processing in 24bit 336 void AdaptBitCount(Bitmap& rNew) const; 337 338 /** Rotate bitmap by the specified angle 339 340 @param nAngle10 341 The rotation angle in tenth of a degree. The bitmap is always rotated around its center. 342 343 @param rFillColor 344 The color to use for filling blank areas. During rotation, the 345 bitmap is enlarged such that the whole rotation result fits 346 in. The empty spaces around that rotated original bitmap are 347 then filled with this color. 348 349 @return true, if the operation was completed successfully. 350 */ 351 bool Rotate( long nAngle10, const Color& rFillColor ); 352 353 /** Create on-off mask from bitmap 354 355 This method creates a bitmask from the bitmap, where every 356 pixel that equals rTransColor is set transparent, the rest 357 opaque. 358 359 @param rTransColor 360 Color value where the bitmask should be transparent 361 362 @param nTol 363 Tolerance value. Specifies the maximal difference between 364 rTransColor and the individual pixel values, such that the 365 corresponding pixel is still regarded as transparent. 366 367 @return the resulting bitmask. 368 */ 369 Bitmap CreateMask( const Color& rTransColor, sal_uInt8 nTol = 0 ) const; 370 371 /** Create region of similar colors in a given rectangle 372 373 @param rColor 374 All pixel which have this color are included in the calculated region 375 376 @param rRect 377 The rectangle within which matching pixel are looked for. This 378 rectangle is always clipped to the bitmap dimensions. 379 380 @return the generated region. 381 */ 382 vcl::Region CreateRegion( const Color& rColor, const tools::Rectangle& rRect ) const; 383 384 /** Replace all pixel where the given mask is on with the specified color 385 386 @param rMask 387 Mask specifying which pixel should be replaced 388 389 @param rReplaceColor 390 Color to be placed in all changed pixel 391 392 @return true, if the operation was completed successfully. 393 */ 394 bool Replace( const Bitmap& rMask, const Color& rReplaceColor ); 395 396 /** Merge bitmap with given background color according to specified alpha mask 397 398 @param rAlpha 399 Alpha mask specifying the amount of background color to merge in 400 401 @param rMergeColor 402 Background color to be used for merging 403 404 @return true, if the operation was completed successfully. 405 */ 406 bool Replace( const AlphaMask& rAlpha, const Color& rMergeColor ); 407 408 /** Replace all pixel having the search color with the specified color 409 410 @param rSearchColor 411 Color specifying which pixel should be replaced 412 413 @param rReplaceColor 414 Color to be placed in all changed pixel 415 416 @param nTol 417 Tolerance value. Specifies the maximal difference between 418 rSearchColor and the individual pixel values, such that the 419 corresponding pixel is still regarded a match. 420 421 @return true, if the operation was completed successfully. 422 */ 423 bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol = 0 ); 424 425 /** Replace all pixel having one the search colors with the corresponding replace color 426 427 @param pSearchColors 428 Array of colors specifying which pixel should be replaced 429 430 @param rReplaceColors 431 Array of colors to be placed in all changed pixel 432 433 @param nColorCount 434 Size of the aforementioned color arrays 435 436 @param pTols 437 Tolerance value. Specifies the maximal difference between 438 pSearchColor colors and the individual pixel values, such that 439 the corresponding pixel is still regarded a match. 440 441 @return true, if the operation was completed successfully. 442 */ 443 bool Replace( 444 const Color* pSearchColors, 445 const Color* rReplaceColors, 446 sal_uLong nColorCount, 447 sal_uInt8 const * pTols ); 448 449 /** Convert the bitmap to a meta file 450 451 This works by putting continuous areas of the same color into 452 polygons painted in this color, by tracing the area's bounding 453 line. 454 455 @param rMtf 456 The resulting meta file 457 458 @param cReduce 459 If non-null, minimal size of bound rects for individual polygons. Smaller ones are ignored. 460 461 @param pProgress 462 A callback for showing the progress of the vectorization 463 */ 464 void Vectorize( 465 GDIMetaFile& rMtf, 466 sal_uInt8 cReduce, 467 const Link<long,void>* pProgress ); 468 469 /** Change various global color characteristics 470 471 @param nLuminancePercent 472 Percent of luminance change, valid range [-100,100]. Values outside this range are clipped to the valid range. 473 474 @param nContrastPercent 475 Percent of contrast change, valid range [-100,100]. Values outside this range are clipped to the valid range. 476 477 @param nChannelRPercent 478 Percent of red channel change, valid range [-100,100]. Values outside this range are clipped to the valid range. 479 480 @param nChannelGPercent 481 Percent of green channel change, valid range [-100,100]. Values outside this range are clipped to the valid range. 482 483 @param nChannelBPercent 484 Percent of blue channel change, valid range [-100,100]. Values outside this range are clipped to the valid range. 485 486 @param fGamma 487 Exponent of the gamma function applied to the bitmap. The 488 value 1.0 results in no change, the valid range is 489 (0.0,10.0]. Values outside this range are regarded as 1.0. 490 491 @param bInvert 492 If true, invert the channel values with the logical 'not' operator 493 494 @param msoBrightness 495 Use the same formula for brightness as used by MSOffice. 496 497 @return true, if the operation was completed successfully. 498 */ 499 bool Adjust( 500 short nLuminancePercent, 501 short nContrastPercent = 0, 502 short nChannelRPercent = 0, 503 short nChannelGPercent = 0, 504 short nChannelBPercent = 0, 505 double fGamma = 1.0, 506 bool bInvert = false, 507 bool msoBrightness = false ); 508 509 public: 510 /** ReassignWithSize and recalculate bitmap. 511 512 ReassignWithSizes the bitmap, and recalculates the bitmap size based on the new bitmap. 513 514 @param rBitmap Bitmap to reassign and use for size calculation 515 */ 516 SAL_DLLPRIVATE void ReassignWithSize(const Bitmap& rBitmap); 517 518 SAL_DLLPRIVATE void ImplMakeUnique(); 519 const std::shared_ptr<SalBitmap>& ImplGetSalBitmap() const { return mxSalBmp; } 520 SAL_DLLPRIVATE void ImplSetSalBitmap( const std::shared_ptr<SalBitmap>& xImpBmp ); 521 522 SAL_DLLPRIVATE bool ImplMakeGreyscales( sal_uInt16 nGreyscales ); 523 524 public: 525 526 BitmapInfoAccess* AcquireInfoAccess(); 527 BitmapReadAccess* AcquireReadAccess(); 528 BitmapWriteAccess* AcquireWriteAccess(); 529 static void ReleaseAccess( BitmapInfoAccess* pAccess ); 530 531 typedef vcl::ScopedBitmapAccess<BitmapReadAccess, Bitmap, &Bitmap::AcquireReadAccess> ScopedReadAccess; 532 typedef vcl::ScopedBitmapAccess<BitmapInfoAccess, Bitmap, &Bitmap::AcquireInfoAccess> ScopedInfoAccess; 533 534 private: 535 SAL_DLLPRIVATE bool ImplConvertUp(sal_uInt16 nBitCount, Color const* pExtColor = nullptr); 536 SAL_DLLPRIVATE bool ImplConvertDown(sal_uInt16 nBitCount, Color const* pExtColor = nullptr); 537 538 private: 539 std::shared_ptr<SalBitmap> mxSalBmp; 540 MapMode maPrefMapMode; 541 Size maPrefSize; 542 543 }; 544 545 inline bool Bitmap::operator!() const 546 { 547 return( mxSalBmp == nullptr ); 548 } 549 550 inline bool Bitmap::IsEmpty() const 551 { 552 return( mxSalBmp == nullptr ); 553 } 554 555 inline const MapMode& Bitmap::GetPrefMapMode() const 556 { 557 return maPrefMapMode; 558 } 559 560 inline void Bitmap::SetPrefMapMode( const MapMode& rMapMode ) 561 { 562 maPrefMapMode = rMapMode; 563 } 564 565 inline const Size& Bitmap::GetPrefSize() const 566 { 567 return maPrefSize; 568 } 569 570 inline void Bitmap::SetPrefSize( const Size& rSize ) 571 { 572 maPrefSize = rSize; 573 } 574 575 inline sal_Int64 Bitmap::GetColorCount() const 576 { 577 return sal_Int64(1) << sal_Int64(GetBitCount()); 578 } 579 580 inline sal_uLong Bitmap::GetSizeBytes() const 581 { 582 const Size aSizePix( GetSizePixel() ); 583 return( ( static_cast<sal_uLong>(aSizePix.Width()) * aSizePix.Height() * GetBitCount() ) >> 3 ); 584 } 585 586 #endif // INCLUDED_VCL_BITMAP_HXX 587 588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 589
