1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_VCL_BITMAP_HXX
21 #define INCLUDED_VCL_BITMAP_HXX
23 #include <tools/color.hxx>
24 #include <tools/link.hxx>
25 #include <tools/solar.h>
26 #include <vcl/checksum.hxx>
27 #include <vcl/dllapi.h>
28 #include <vcl/mapmod.hxx>
29 #include <vcl/region.hxx>
30 #include <vcl/scopedbitmapaccess.hxx>
31 #include <o3tl/typed_flags_set.hxx>
33 enum class BmpMirrorFlags
41 template<> struct typed_flags
<BmpMirrorFlags
> : is_typed_flags
<BmpMirrorFlags
, 0x03> {};
45 enum class BmpScaleFlag
47 // Try to preferably use these.
51 // Specific algorithms, use only if you really need to.
59 enum class BmpDitherFlags
68 template<> struct typed_flags
<BmpDitherFlags
> : is_typed_flags
<BmpDitherFlags
, 0x07> {};
71 #define BMP_COL_TRANS Color( 252, 3, 251 )
73 enum class BmpConversion
93 BMP_REDUCE_SIMPLE
= 0,
94 BMP_REDUCE_POPULAR
= 1
113 class VCL_DLLPUBLIC BmpFilterParam
117 BmpFilterParam( sal_uLong nProgressStart
= 0, sal_uLong nProgressEnd
= 0 ) :
118 meFilter( BmpFilter::Unknown
), mnProgressStart( nProgressStart
), mnProgressEnd( nProgressEnd
) {}
120 BmpFilterParam( sal_uInt8 cSolarGreyThreshold
, sal_uLong nProgressStart
= 0, sal_uLong nProgressEnd
= 0 ) :
121 meFilter( BmpFilter::Solarize
), mnProgressStart( nProgressStart
), mnProgressEnd( nProgressEnd
),
122 mcSolarGreyThreshold( cSolarGreyThreshold
) {}
124 BmpFilterParam( double nRadius
, sal_uLong nProgressStart
= 0, sal_uLong nProgressEnd
= 0 ) :
125 meFilter( BmpFilter::Smooth
), mnProgressStart( nProgressStart
), mnProgressEnd( nProgressEnd
),
126 mnRadius( nRadius
) {}
128 BmpFilterParam( sal_uInt16 nSepiaPercent
, sal_uLong nProgressStart
= 0, sal_uLong nProgressEnd
= 0 ) :
129 meFilter( BmpFilter::Sepia
), mnProgressStart( nProgressStart
), mnProgressEnd( nProgressEnd
),
130 mnSepiaPercent( nSepiaPercent
)
132 assert(nSepiaPercent
<=100);
135 BmpFilterParam( const Size
& rMosaicTileSize
, sal_uLong nProgressStart
= 0, sal_uLong nProgressEnd
= 0 ) :
136 meFilter( BmpFilter::Mosaic
), mnProgressStart( nProgressStart
), mnProgressEnd( nProgressEnd
)
138 maMosaicTileSize
.mnTileWidth
= rMosaicTileSize
.Width();
139 maMosaicTileSize
.mnTileHeight
= rMosaicTileSize
.Height();
141 BmpFilterParam( sal_uInt16 nEmbossAzimuthAngle100
, sal_uInt16 nEmbossElevationAngle100
,
142 sal_uLong nProgressStart
= 0, sal_uLong nProgressEnd
= 0 ) :
143 meFilter( BmpFilter::EmbossGrey
), mnProgressStart( nProgressStart
), mnProgressEnd( nProgressEnd
)
145 maEmbossAngles
.mnAzimuthAngle100
= nEmbossAzimuthAngle100
;
146 maEmbossAngles
.mnElevationAngle100
= nEmbossElevationAngle100
;
150 friend class ::Bitmap
;
151 friend class BitmapEx
;
152 friend class Animation
;
156 sal_uLong mnProgressStart
;
157 sal_uLong mnProgressEnd
;
160 struct MosaicTileSize
162 sal_uLong mnTileWidth
;
163 sal_uLong mnTileHeight
;
168 sal_uInt16 mnAzimuthAngle100
;
169 sal_uInt16 mnElevationAngle100
;
175 sal_uInt16 mnSepiaPercent
;
176 sal_uInt8 mcSolarGreyThreshold
;
179 MosaicTileSize maMosaicTileSize
;
180 EmbossAngles maEmbossAngles
;
185 class BitmapInfoAccess
;
186 class BitmapReadAccess
;
187 class BitmapWriteAccess
;
200 struct BitmapSystemData
203 void* pDIB
; // device independent byte buffer
204 void* pDDB
; // if not NULL then this is actually an HBITMAP
205 #elif defined( MACOSX ) || defined( IOS )
206 void* rImageContext
; //Image context (CGContextRef)
214 class VCL_DLLPUBLIC Bitmap
219 Bitmap( const Bitmap
& rBitmap
);
220 Bitmap( const Size
& rSizePixel
, sal_uInt16 nBitCount
, const BitmapPalette
* pPal
= nullptr );
221 Bitmap( SalBitmap
* pSalBitmap
);
224 Bitmap
& operator=( const Bitmap
& rBitmap
);
225 Bitmap
& operator=( Bitmap
&& rBitmap
);
226 inline bool operator!() const;
227 inline bool operator==( const Bitmap
& rBitmap
) const;
228 inline bool operator!=( const Bitmap
& rBitmap
) const;
230 bool IsEqual( const Bitmap
& rBmp
) const;
232 inline bool IsEmpty() const;
235 inline const MapMode
& GetPrefMapMode() const;
236 inline void SetPrefMapMode( const MapMode
& rMapMode
);
238 inline const Size
& GetPrefSize() const;
239 inline void SetPrefSize( const Size
& rSize
);
241 Size
GetSizePixel() const;
243 sal_uInt16
GetBitCount() const;
244 inline sal_uLong
GetColorCount() const;
245 inline sal_uLong
GetSizeBytes() const;
246 bool HasGreyPalette() const;
247 /** get system dependent bitmap data
250 The system dependent BitmapSystemData structure to be filled
252 @return true if the bitmap has a valid system object (e.g. not empty)
254 bool GetSystemData( BitmapSystemData
& rData
) const;
256 BitmapChecksum
GetChecksum() const;
258 Bitmap
CreateDisplayBitmap( OutputDevice
* pDisplay
);
260 static const BitmapPalette
&
261 GetGreyPalette( int nEntries
);
265 bool MakeMono( sal_uInt8 cThreshold
);
268 /** Convert bitmap format
271 The format this bitmap should be converted to.
273 @return true, if the conversion was completed successfully.
275 bool Convert( BmpConversion eConversion
);
277 /** Reduce number of colors for the bitmap
279 @param nNewColorCount
280 Maximal number of bitmap colors after the reduce operation
283 Algorithm to use for color reduction
285 @return true, if the color reduction operation was completed successfully.
288 sal_uInt16 nNewColorCount
,
289 BmpReduce eReduce
= BMP_REDUCE_SIMPLE
);
291 /** Apply a dither algorithm to the bitmap
293 This method dithers the bitmap inplace, i.e. a true color
294 bitmap is converted to a paletted bitmap, reducing the color
295 deviation by error diffusion.
298 The algorithm to be used for dithering
300 bool Dither( BmpDitherFlags nDitherFlags
= BmpDitherFlags::Matrix
);
305 A rectangle specifying the crop amounts on all four sides of
306 the bitmap. If the upper left corner of the bitmap is assigned
307 (0,0), then this method cuts out the given rectangle from the
308 bitmap. Note that the rectangle is clipped to the bitmap's
309 dimension, i.e. negative left,top rectangle coordinates or
310 exceeding width or height is ignored.
312 @return true, if cropping was performed successfully. If
313 nothing had to be cropped, because e.g. the crop rectangle
314 included the bitmap, false is returned, too!
316 bool Crop( const tools::Rectangle
& rRectPixel
);
318 /** Expand the bitmap by pixel padding
321 Number of pixel to pad at the right border of the bitmap
324 Number of scanlines to pad at the bottom border of the bitmap
327 Color to use for padded pixel
329 @return true, if padding was performed successfully. false is
330 not only returned when the operation failed, but also if
331 nothing had to be done, e.g. because nDX and nDY were zero.
334 sal_uLong nDX
, sal_uLong nDY
,
335 const Color
* pInitColor
= nullptr );
337 /** Copy a rectangular area from another bitmap
340 Destination rectangle in this bitmap. This is clipped to the
344 Source rectangle in pBmpSrc. This is clipped to the source
345 bitmap dimensions. Note further that no scaling takes place
346 during this copy operation, i.e. only the minimum of source
347 and destination rectangle's width and height are used.
350 The source bitmap to copy from. If this argument is NULL, or
351 equal to the object this method is called on, copying takes
352 place within the same bitmap.
354 @return true, if the operation completed successfully. false
355 is not only returned when the operation failed, but also if
356 nothing had to be done, e.g. because one of the rectangles are
360 const tools::Rectangle
& rRectDst
,
361 const tools::Rectangle
& rRectSrc
,
362 const Bitmap
* pBmpSrc
= nullptr );
364 bool CopyPixel_AlphaOptimized(
365 const tools::Rectangle
& rRectDst
,
366 const tools::Rectangle
& rRectSrc
,
367 const Bitmap
* pBmpSrc
);
369 /** Perform boolean operations with another bitmap
372 The mask bitmap in the selected combine operation
375 The combine operation to perform on the bitmap
377 @return true, if the operation was completed successfully.
381 BmpCombine eCombine
);
383 /** Alpha-blend the given bitmap against a specified uniform
386 @attention This method might convert paletted bitmaps to
387 truecolor, to be able to represent every necessary color. Note
388 that during alpha blending, lots of colors not originally
389 included in the bitmap can be generated.
392 Alpha mask to blend with
394 @param rBackgroundColor
395 Background color to use for every pixel during alpha blending
397 @return true, if blending was successful, false otherwise
400 const AlphaMask
& rAlpha
,
401 const Color
& rBackgroundColor
);
403 /** Fill the entire bitmap with the given color
406 Color value to use for filling
408 @return true, if the operation was completed successfully.
410 bool Erase( const Color
& rFillColor
);
412 /** Perform the Invert operation on every pixel
414 @return true, if the operation was completed successfully.
418 /** Mirror the bitmap
421 About which axis (horizontal, vertical, or both) to mirror
423 @return true, if the operation was completed successfully.
425 bool Mirror( BmpMirrorFlags nMirrorFlags
);
430 The resulting size of the scaled bitmap
433 The algorithm to be used for scaling
435 @return true, if the operation was completed successfully.
437 bool Scale( const Size
& rNewSize
, BmpScaleFlag nScaleFlag
= BmpScaleFlag::Default
);
442 The scale factor in x direction.
445 The scale factor in y direction.
448 Method of scaling - it is recommended that either BmpScaleFlag::Default or BmpScaleFlag::BestQuality be used.
450 @return true, if the operation was completed successfully.
452 bool Scale( const double& rScaleX
, const double& rScaleY
, BmpScaleFlag nScaleFlag
= BmpScaleFlag::Default
);
455 Returns true if bitmap scaling is considered to be fast.
457 Currently this returns true if OpenGL is used for scaling, otherwise false (CPU scaling is slower).
461 static bool HasFastScale();
463 // Adapt the BitCount of rNew to BitCount of total, including grey or color palette
464 // Can be used to create alpha/mask bitmaps after their processing in 24bit
465 void AdaptBitCount(Bitmap
& rNew
) const;
467 /** Rotate bitmap by the specified angle
470 The rotation angle in tenth of a degree. The bitmap is always rotated around its center.
473 The color to use for filling blank areas. During rotation, the
474 bitmap is enlarged such that the whole rotation result fits
475 in. The empty spaces around that rotated original bitmap are
476 then filled with this color.
478 @return true, if the operation was completed successfully.
480 bool Rotate( long nAngle10
, const Color
& rFillColor
);
482 /** Create on-off mask from bitmap
484 This method creates a bitmask from the bitmap, where every
485 pixel that equals rTransColor is set transparent, the rest
489 Color value where the bitmask should be transparent
492 Tolerance value. Specifies the maximal difference between
493 rTransColor and the individual pixel values, such that the
494 corresponding pixel is still regarded transparent.
496 @return the resulting bitmask.
498 Bitmap
CreateMask( const Color
& rTransColor
, sal_uLong nTol
= 0UL ) const;
500 /** Create region of similar colors in a given rectangle
503 All pixel which have this color are included in the calculated region
506 The rectangle within which matching pixel are looked for. This
507 rectangle is always clipped to the bitmap dimensions.
509 @return the generated region.
511 vcl::Region
CreateRegion( const Color
& rColor
, const tools::Rectangle
& rRect
) const;
513 /** Replace all pixel where the given mask is on with the specified color
516 Mask specifying which pixel should be replaced
519 Color to be placed in all changed pixel
521 @return true, if the operation was completed successfully.
523 bool Replace( const Bitmap
& rMask
, const Color
& rReplaceColor
);
525 /** Merge bitmap with given background color according to specified alpha mask
528 Alpha mask specifying the amount of background color to merge in
531 Background color to be used for merging
533 @return true, if the operation was completed successfully.
535 bool Replace( const AlphaMask
& rAlpha
, const Color
& rMergeColor
);
537 /** Replace all pixel having the search color with the specified color
540 Color specifying which pixel should be replaced
543 Color to be placed in all changed pixel
546 Tolerance value. Specifies the maximal difference between
547 rSearchColor and the individual pixel values, such that the
548 corresponding pixel is still regarded a match.
550 @return true, if the operation was completed successfully.
552 bool Replace( const Color
& rSearchColor
, const Color
& rReplaceColor
, sal_uLong nTol
= 0 );
554 /** Replace all pixel having one the search colors with the corresponding replace color
557 Array of colors specifying which pixel should be replaced
559 @param rReplaceColors
560 Array of colors to be placed in all changed pixel
563 Size of the aforementioned color arrays
566 Tolerance value. Specifies the maximal difference between
567 pSearchColor colors and the individual pixel values, such that
568 the corresponding pixel is still regarded a match.
570 @return true, if the operation was completed successfully.
573 const Color
* pSearchColors
,
574 const Color
* rReplaceColors
,
575 sal_uLong nColorCount
,
576 sal_uLong
* pTols
= nullptr );
578 /** Convert the bitmap to a meta file
580 This works by putting continuous areas of the same color into
581 polygons painted in this color, by tracing the area's bounding
585 The resulting meta file
588 If non-null, minimal size of bound rects for individual polygons. Smaller ones are ignored.
591 A callback for showing the progress of the vectorization
593 @return true, if the operation was completed successfully.
598 const Link
<long,void>* pProgress
);
600 /** Change various global color characteristics
602 @param nLuminancePercent
603 Percent of luminance change, valid range [-100,100]. Values outside this range are clipped to the valid range.
605 @param nContrastPercent
606 Percent of contrast change, valid range [-100,100]. Values outside this range are clipped to the valid range.
608 @param nChannelRPercent
609 Percent of red channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
611 @param nChannelGPercent
612 Percent of green channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
614 @param nChannelBPercent
615 Percent of blue channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
618 Exponent of the gamma function applied to the bitmap. The
619 value 1.0 results in no change, the valid range is
620 (0.0,10.0]. Values outside this range are regarded as 1.0.
623 If true, invert the channel values with the logical 'not' operator
626 Use the same formula for brightness as used by MSOffice.
628 @return true, if the operation was completed successfully.
631 short nLuminancePercent
,
632 short nContrastPercent
= 0,
633 short nChannelRPercent
= 0,
634 short nChannelGPercent
= 0,
635 short nChannelBPercent
= 0,
637 bool bInvert
= false,
638 bool msoBrightness
= false );
640 /** Apply specified filter to the bitmap
643 The filter algorithm to apply
646 Various parameter for the different bitmap filter algorithms
648 @return true, if the operation was completed successfully.
652 const BmpFilterParam
* pFilterParam
= nullptr );
656 SAL_DLLPRIVATE
void ImplMakeUnique();
657 const std::shared_ptr
<ImpBitmap
>& ImplGetImpBitmap() const { return mxImpBmp
; }
658 SAL_DLLPRIVATE
void ImplSetImpBitmap( const std::shared_ptr
<ImpBitmap
>& xImpBmp
);
659 SAL_DLLPRIVATE
void ImplAssignWithSize( const Bitmap
& rBitmap
);
661 SAL_DLLPRIVATE
void ImplAdaptBitCount(Bitmap
& rNew
) const;
662 SAL_DLLPRIVATE
bool ImplScaleFast( const double& rScaleX
, const double& rScaleY
);
663 SAL_DLLPRIVATE
bool ImplScaleInterpolate( const double& rScaleX
, const double& rScaleY
);
665 SAL_DLLPRIVATE
bool ImplConvolutionPass(
667 BitmapReadAccess
* pReadAcc
,
668 int aNumberOfContributions
,
673 SAL_DLLPRIVATE
bool ImplMakeMono( sal_uInt8 cThreshold
);
674 SAL_DLLPRIVATE
bool ImplMakeGreyscales( sal_uInt16 nGreyscales
);
675 SAL_DLLPRIVATE
bool ImplConvertUp( sal_uInt16 nBitCount
, Color
* pExtColor
= nullptr );
676 SAL_DLLPRIVATE
bool ImplConvertDown( sal_uInt16 nBitCount
, Color
* pExtColor
= nullptr );
677 SAL_DLLPRIVATE
bool ImplConvertGhosted();
678 SAL_DLLPRIVATE
bool ImplDitherMatrix();
679 SAL_DLLPRIVATE
bool ImplDitherFloyd();
680 SAL_DLLPRIVATE
bool ImplDitherFloyd16();
681 SAL_DLLPRIVATE
bool ImplReduceSimple( sal_uInt16 nColorCount
);
682 SAL_DLLPRIVATE
bool ImplReducePopular( sal_uInt16 nColorCount
);
683 SAL_DLLPRIVATE
bool ImplReduceMedian( sal_uInt16 nColorCount
);
684 SAL_DLLPRIVATE
void ImplMedianCut(
687 long nR1
, long nR2
, long nG1
, long nG2
, long nB1
, long nB2
,
688 long nColors
, long nPixels
, long& rIndex
);
690 SAL_DLLPRIVATE
bool ImplConvolute3( const long* pMatrix
);
692 SAL_DLLPRIVATE
bool ImplMedianFilter();
693 SAL_DLLPRIVATE
bool ImplSobelGrey();
694 SAL_DLLPRIVATE
bool ImplEmbossGrey( const BmpFilterParam
* pFilterParam
);
695 SAL_DLLPRIVATE
bool ImplSolarize( const BmpFilterParam
* pFilterParam
);
696 SAL_DLLPRIVATE
bool ImplSepia( const BmpFilterParam
* pFilterParam
);
697 SAL_DLLPRIVATE
bool ImplMosaic( const BmpFilterParam
* pFilterParam
);
698 SAL_DLLPRIVATE
bool ImplPopArt();
700 SAL_DLLPRIVATE
bool ImplSeparableBlurFilter( const double aRadius
);
701 SAL_DLLPRIVATE
bool ImplSeparableUnsharpenFilter( const double aRadius
);
702 SAL_DLLPRIVATE
bool ImplDuotoneFilter( const sal_uLong nColorOne
, sal_uLong nColorTwo
);
703 SAL_DLLPRIVATE
static void ImplBlurContributions(
705 const int aNumberOfContributions
,
713 BitmapInfoAccess
* AcquireInfoAccess();
714 BitmapReadAccess
* AcquireReadAccess();
715 BitmapWriteAccess
* AcquireWriteAccess();
716 static void ReleaseAccess( BitmapInfoAccess
* pAccess
);
718 typedef vcl::ScopedBitmapAccess
<BitmapReadAccess
, Bitmap
, &Bitmap::AcquireReadAccess
> ScopedReadAccess
;
719 typedef vcl::ScopedBitmapAccess
<BitmapWriteAccess
, Bitmap
, &Bitmap::AcquireWriteAccess
> ScopedWriteAccess
;
720 typedef vcl::ScopedBitmapAccess
<BitmapInfoAccess
, Bitmap
, &Bitmap::AcquireInfoAccess
> ScopedInfoAccess
;
724 std::shared_ptr
<ImpBitmap
> mxImpBmp
;
725 MapMode maPrefMapMode
;
730 inline bool Bitmap::operator!() const
732 return( mxImpBmp
== nullptr );
735 inline bool Bitmap::operator==( const Bitmap
& rBitmap
) const
737 return( rBitmap
.mxImpBmp
== mxImpBmp
);
740 inline bool Bitmap::operator!=( const Bitmap
& rBitmap
) const
742 return( rBitmap
.mxImpBmp
!= mxImpBmp
);
745 inline bool Bitmap::IsEmpty() const
747 return( mxImpBmp
== nullptr );
750 inline const MapMode
& Bitmap::GetPrefMapMode() const
752 return maPrefMapMode
;
755 inline void Bitmap::SetPrefMapMode( const MapMode
& rMapMode
)
757 maPrefMapMode
= rMapMode
;
760 inline const Size
& Bitmap::GetPrefSize() const
765 inline void Bitmap::SetPrefSize( const Size
& rSize
)
770 inline sal_uLong
Bitmap::GetColorCount() const
772 return( (sal_uLong
)1 << (sal_uLong
) GetBitCount() );
775 inline sal_uLong
Bitmap::GetSizeBytes() const
777 const Size
aSizePix( GetSizePixel() );
778 return( ( (sal_uLong
) aSizePix
.Width() * aSizePix
.Height() * GetBitCount() ) >> 3UL );
781 #endif // INCLUDED_VCL_BITMAP_HXX
783 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */