Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / include / vcl / bitmap.hxx
bloba732e77f3a97cdf1a581b2ea374a5823e4cb362c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/degree.hxx>
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 <vcl/bitmap/BitmapTypes.hxx>
31 #include <o3tl/typed_flags_set.hxx>
33 #include <memory>
35 #define GAMMA( _def_cVal, _def_InvGamma ) (static_cast<sal_uInt8>(MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0,255)))
37 class Color;
39 template <typename Arg, typename Ret> class Link;
41 enum class BmpMirrorFlags
43 NONE = 0x00,
44 Horizontal = 0x01,
45 Vertical = 0x02,
48 namespace o3tl
50 template<> struct typed_flags<BmpMirrorFlags> : is_typed_flags<BmpMirrorFlags, 0x03> {};
53 enum class BmpScaleFlag
55 // Try to preferably use these.
56 Default,
57 Fast,
58 BestQuality,
59 // Specific algorithms, use only if you really need to (mainly used for tests)
60 NearestNeighbor,
61 Interpolate, // fast, integer bilinear
62 Lanczos,
63 BiCubic,
64 BiLinear
67 #define BMP_COL_TRANS Color( 252, 3, 251 )
69 enum class BmpConversion
71 NNONE,
72 N1BitThreshold,
73 N8BitGreys,
74 N8BitColors,
75 N24Bit,
76 N32Bit,
77 N8BitTrans,
78 N8BitNoConversion // make 8bit without color conversion (e.g. take the red channel)
81 class BitmapInfoAccess;
82 class BitmapReadAccess;
83 class BitmapWriteAccess;
84 class BitmapPalette;
85 class GDIMetaFile;
86 class AlphaMask;
87 class OutputDevice;
88 class SalBitmap;
90 namespace basegfx { class SystemDependentDataHolder; }
92 struct BitmapSystemData
94 #if defined(_WIN32)
95 void* pDIB; // device independent byte buffer
96 #elif defined( MACOSX ) || defined( IOS )
97 // Nothing needed, apparently
98 #else
99 void* aPixmap;
100 #endif
101 int mnWidth;
102 int mnHeight;
105 class SAL_WARN_UNUSED VCL_DLLPUBLIC Bitmap
107 public:
109 Bitmap();
110 Bitmap( const Bitmap& rBitmap );
111 Bitmap( const Size& rSizePixel, vcl::PixelFormat ePixelFormat, const BitmapPalette* pPal = nullptr );
112 explicit Bitmap( std::shared_ptr<SalBitmap> xSalBitmap );
113 virtual ~Bitmap();
115 Bitmap& operator=( const Bitmap& rBitmap );
116 Bitmap& operator=( Bitmap&& rBitmap ) noexcept;
117 bool operator==( const Bitmap& rBitmap ) const;
118 bool operator!=( const Bitmap& rBitmap ) const { return !operator==(rBitmap); }
120 inline bool IsEmpty() const;
121 void SetEmpty();
123 inline const MapMode& GetPrefMapMode() const;
124 inline void SetPrefMapMode( const MapMode& rMapMode );
126 inline const Size& GetPrefSize() const;
127 inline void SetPrefSize( const Size& rSize );
129 Size GetSizePixel() const;
131 vcl::PixelFormat getPixelFormat() const;
132 inline sal_Int64 GetSizeBytes() const;
133 bool HasGreyPalette8Bit() const;
134 bool HasGreyPaletteAny() const;
135 /** get system dependent bitmap data
137 @param rData
138 The system dependent BitmapSystemData structure to be filled
140 @return true if the bitmap has a valid system object (e.g. not empty)
142 bool GetSystemData( BitmapSystemData& rData ) const;
144 BitmapChecksum GetChecksum() const;
146 Bitmap CreateDisplayBitmap( OutputDevice* pDisplay ) const;
148 static const BitmapPalette&
149 GetGreyPalette( int nEntries );
151 public:
153 /** Convert bitmap format
155 @param eConversion
156 The format this bitmap should be converted to.
158 @return true the conversion was completed successfully.
160 bool Convert( BmpConversion eConversion );
162 /** Apply a Floyd dither algorithm to the bitmap
164 This method dithers the bitmap inplace, i.e. a true color
165 bitmap is converted to a paletted bitmap, reducing the color
166 deviation by error diffusion.
169 bool Dither();
171 /** Crop the bitmap
173 @param rRectPixel
174 A rectangle specifying the crop amounts on all four sides of
175 the bitmap. If the upper left corner of the bitmap is assigned
176 (0,0), then this method cuts out the given rectangle from the
177 bitmap. Note that the rectangle is clipped to the bitmap's
178 dimension, i.e. negative left,top rectangle coordinates or
179 exceeding width or height is ignored.
181 @return true cropping was performed successfully. If
182 nothing had to be cropped, because e.g. the crop rectangle
183 included the bitmap, false is returned, too!
185 bool Crop( const tools::Rectangle& rRectPixel );
187 /** Expand the bitmap by pixel padding
189 @param nDX
190 Number of pixel to pad at the right border of the bitmap
192 @param nDY
193 Number of scanlines to pad at the bottom border of the bitmap
195 @param pInitColor
196 Color to use for padded pixel
198 @return true, if padding was performed successfully. false is
199 not only returned when the operation failed, but also if
200 nothing had to be done, e.g. because nDX and nDY were zero.
202 bool Expand(
203 sal_Int32 nDX, sal_Int32 nDY,
204 const Color* pInitColor = nullptr );
206 /** Copy a rectangular area from another bitmap
208 @param rRectDst
209 Destination rectangle in this bitmap. This is clipped to the
210 bitmap dimensions.
212 @param rRectSrc
213 Source rectangle in pBmpSrc. This is clipped to the source
214 bitmap dimensions. Note further that no scaling takes place
215 during this copy operation, i.e. only the minimum of source
216 and destination rectangle's width and height are used.
218 @param pBmpSrc
219 The source bitmap to copy from. If this argument is NULL, or
220 equal to the object this method is called on, copying takes
221 place within the same bitmap.
223 @return true, if the operation completed successfully. false
224 is not only returned when the operation failed, but also if
225 nothing had to be done, e.g. because one of the rectangles are
226 empty.
228 bool CopyPixel(
229 const tools::Rectangle& rRectDst,
230 const tools::Rectangle& rRectSrc,
231 const Bitmap* pBmpSrc = nullptr );
233 bool CopyPixel_AlphaOptimized(
234 const tools::Rectangle& rRectDst,
235 const tools::Rectangle& rRectSrc,
236 const Bitmap* pBmpSrc );
238 /** Perform boolean OR operation with another bitmap
240 @param rMask
241 The mask bitmap in the selected combine operation
243 @return true, if the operation was completed successfully.
245 bool CombineOr( const Bitmap& rMask );
247 /** Alpha-blend the given bitmap against a specified uniform
248 background color.
250 @attention This method might convert paletted bitmaps to
251 truecolor, to be able to represent every necessary color. Note
252 that during alpha blending, lots of colors not originally
253 included in the bitmap can be generated.
255 @param rAlpha
256 Alpha mask to blend with
258 @param rBackgroundColor
259 Background color to use for every pixel during alpha blending
261 @return true, if blending was successful, false otherwise
263 bool Blend(
264 const AlphaMask& rAlpha,
265 const Color& rBackgroundColor );
267 /** Fill the entire bitmap with the given color
269 @param rFillColor
270 Color value to use for filling
272 @return true, if the operation was completed successfully.
274 bool Erase( const Color& rFillColor );
276 /** Perform the Invert operation on every pixel
278 @return true, if the operation was completed successfully.
280 bool Invert();
282 /** Mirror the bitmap
284 @param nMirrorFlags
285 About which axis (horizontal, vertical, or both) to mirror
287 @return true, if the operation was completed successfully.
289 bool Mirror( BmpMirrorFlags nMirrorFlags );
291 /** Scale the bitmap
293 @param rNewSize
294 The resulting size of the scaled bitmap
296 @param nScaleFlag
297 The algorithm to be used for scaling
299 @return true, if the operation was completed successfully.
301 bool Scale( const Size& rNewSize, BmpScaleFlag nScaleFlag = BmpScaleFlag::Default );
303 /** Scale the bitmap
305 @param rScaleX
306 The scale factor in x direction.
308 @param rScaleY
309 The scale factor in y direction.
311 @param nScaleFlag
312 Method of scaling - it is recommended that either BmpScaleFlag::Default or BmpScaleFlag::BestQuality be used.
314 @return true, if the operation was completed successfully.
316 bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag = BmpScaleFlag::Default );
319 Returns true if bitmap scaling is considered to be fast.
321 Currently this returns true if OpenGL is used for scaling, otherwise false (CPU scaling is slower).
323 @since 4.5
325 static bool HasFastScale();
327 // Adapt the BitCount of rNew to BitCount of total, including grey or color palette
328 // Can be used to create alpha/mask bitmaps after their processing in 24bit
329 void AdaptBitCount(Bitmap& rNew) const;
331 /** Rotate bitmap by the specified angle
333 @param nAngle10
334 The rotation angle in tenth of a degree. The bitmap is always rotated around its center.
336 @param rFillColor
337 The color to use for filling blank areas. During rotation, the
338 bitmap is enlarged such that the whole rotation result fits
339 in. The empty spaces around that rotated original bitmap are
340 then filled with this color.
342 @return true, if the operation was completed successfully.
344 bool Rotate( Degree10 nAngle10, const Color& rFillColor );
346 /** Create on-off mask from bitmap
348 This method creates a bitmask from the bitmap, where every
349 pixel that equals rTransColor is set transparent, the rest
350 opaque.
352 @param rTransColor
353 Color value where the bitmask should be transparent
355 @return the resulting bitmask.
357 Bitmap CreateMask( const Color& rTransColor ) const;
359 /** Create on-off mask from bitmap
361 This method creates a bitmask from the bitmap, where every
362 pixel that equals rTransColor is set transparent, the rest
363 opaque.
365 @param rTransColor
366 Color value where the bitmask should be transparent
368 @param nTol
369 Tolerance value. Specifies the maximal difference between
370 rTransColor and the individual pixel values, such that the
371 corresponding pixel is still regarded as transparent.
373 @return the resulting bitmask.
375 Bitmap CreateMask( const Color& rTransColor, sal_uInt8 nTol ) const;
377 /** Create region of similar colors in a given rectangle
379 @param rColor
380 All pixel which have this color are included in the calculated region
382 @param rRect
383 The rectangle within which matching pixel are looked for. This
384 rectangle is always clipped to the bitmap dimensions.
386 @return the generated region.
388 vcl::Region CreateRegion( const Color& rColor, const tools::Rectangle& rRect ) const;
390 /** Replace all pixel where the given mask is on with the specified color
392 @param rMask
393 Mask specifying which pixel should be replaced
395 @param rReplaceColor
396 Color to be placed in all changed pixel
398 @return true, if the operation was completed successfully.
400 bool Replace( const Bitmap& rMask, const Color& rReplaceColor );
402 /** Merge bitmap with given background color according to specified alpha mask
404 @param rAlpha
405 Alpha mask specifying the amount of background color to merge in
407 @param rMergeColor
408 Background color to be used for merging
410 @return true, if the operation was completed successfully.
412 bool Replace( const AlphaMask& rAlpha, const Color& rMergeColor );
414 /** Replace all pixel having the search color with the specified color
416 @param rSearchColor
417 Color specifying which pixel should be replaced
419 @param rReplaceColor
420 Color to be placed in all changed pixel
422 @param nTol
423 Tolerance value. Specifies the maximal difference between
424 rSearchColor and the individual pixel values, such that the
425 corresponding pixel is still regarded a match.
427 @return true, if the operation was completed successfully.
429 bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol = 0 );
431 /** Replace all pixel having one the search colors with the corresponding replace color
433 @param pSearchColors
434 Array of colors specifying which pixel should be replaced
436 @param rReplaceColors
437 Array of colors to be placed in all changed pixel
439 @param nColorCount
440 Size of the aforementioned color arrays
442 @param pTols
443 Tolerance value. Specifies the maximal difference between
444 pSearchColor colors and the individual pixel values, such that
445 the corresponding pixel is still regarded a match.
447 @return true, if the operation was completed successfully.
449 bool Replace(
450 const Color* pSearchColors,
451 const Color* rReplaceColors,
452 size_t nColorCount,
453 sal_uInt8 const * pTols );
455 /** Convert the bitmap to a meta file
457 This works by putting continuous areas of the same color into
458 polygons painted in this color, by tracing the area's bounding
459 line.
461 @param rMtf
462 The resulting meta file
464 @param cReduce
465 If non-null, minimal size of bound rects for individual polygons. Smaller ones are ignored.
467 @param pProgress
468 A callback for showing the progress of the vectorization
470 void Vectorize(
471 GDIMetaFile& rMtf,
472 sal_uInt8 cReduce,
473 const Link<tools::Long,void>* pProgress );
475 /** Change various global color characteristics
477 @param nLuminancePercent
478 Percent of luminance change, valid range [-100,100]. Values outside this range are clipped to the valid range.
480 @param nContrastPercent
481 Percent of contrast change, valid range [-100,100]. Values outside this range are clipped to the valid range.
483 @param nChannelRPercent
484 Percent of red channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
486 @param nChannelGPercent
487 Percent of green channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
489 @param nChannelBPercent
490 Percent of blue channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
492 @param fGamma
493 Exponent of the gamma function applied to the bitmap. The
494 value 1.0 results in no change, the valid range is
495 (0.0,10.0]. Values outside this range are regarded as 1.0.
497 @param bInvert
498 If true, invert the channel values with the logical 'not' operator
500 @param msoBrightness
501 Use the same formula for brightness as used by MSOffice.
503 @return true, if the operation was completed successfully.
505 bool Adjust(
506 short nLuminancePercent,
507 short nContrastPercent = 0,
508 short nChannelRPercent = 0,
509 short nChannelGPercent = 0,
510 short nChannelBPercent = 0,
511 double fGamma = 1.0,
512 bool bInvert = false,
513 bool msoBrightness = false );
515 /** Remove existing blending against COL_WHITE based on given AlphaMask
517 Inside convertToBitmapEx the content gets rendered to RGB target (no 'A'),
518 so it gets blended against the start condition of the target device which
519 is blank (usually white background, but others may be used).
520 Usually rendering to RGB is sufficient (e.g. EditViews), but for conversion
521 to BitmapEx the alpha channel is needed to e.g. allow export/conversion to
522 pixel target formats which support Alpha, e.g. PNG.
523 It is possible though to create the fully valid and correct AlphaChannel.
524 If the content, the start condition and the alpha values are known it is
525 possible to calculate back ("remove") the white blending from the result,
526 and this is what this method does.
528 @param rColor
529 The Color we know this Bitmap is blended against (usually COL_WHITE)
531 @param rAlphaMask
532 The AlphaMask which was used to blend white against this
534 void RemoveBlendedStartColor(
535 const Color& rColor,
536 const AlphaMask& rAlphaMask);
538 // access to SystemDependentDataHolder, to support overload in derived class(es)
539 const basegfx::SystemDependentDataHolder* accessSystemDependentDataHolder() const;
541 public:
542 /** ReassignWithSize and recalculate bitmap.
544 ReassignWithSizes the bitmap, and recalculates the bitmap size based on the new bitmap.
546 @param rBitmap Bitmap to reassign and use for size calculation
548 SAL_DLLPRIVATE void ReassignWithSize(const Bitmap& rBitmap);
550 SAL_DLLPRIVATE void ImplMakeUnique();
551 const std::shared_ptr<SalBitmap>& ImplGetSalBitmap() const { return mxSalBmp; }
552 SAL_DLLPRIVATE void ImplSetSalBitmap( const std::shared_ptr<SalBitmap>& xImpBmp );
554 SAL_DLLPRIVATE bool ImplMakeGreyscales();
556 public:
558 BitmapInfoAccess* AcquireInfoAccess();
559 BitmapReadAccess* AcquireReadAccess();
560 BitmapWriteAccess* AcquireWriteAccess();
561 static void ReleaseAccess( BitmapInfoAccess* pAccess );
563 typedef vcl::ScopedBitmapAccess<BitmapReadAccess, Bitmap, &Bitmap::AcquireReadAccess> ScopedReadAccess;
564 typedef vcl::ScopedBitmapAccess<BitmapInfoAccess, Bitmap, &Bitmap::AcquireInfoAccess> ScopedInfoAccess;
566 private:
567 SAL_DLLPRIVATE bool ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const* pExtColor = nullptr);
568 SAL_DLLPRIVATE bool ImplConvertDown8BPP(Color const* pExtColor = nullptr);
570 private:
571 std::shared_ptr<SalBitmap> mxSalBmp;
572 MapMode maPrefMapMode;
573 Size maPrefSize;
576 inline bool Bitmap::IsEmpty() const
578 return( mxSalBmp == nullptr );
581 inline const MapMode& Bitmap::GetPrefMapMode() const
583 return maPrefMapMode;
586 inline void Bitmap::SetPrefMapMode( const MapMode& rMapMode )
588 maPrefMapMode = rMapMode;
591 inline const Size& Bitmap::GetPrefSize() const
593 return maPrefSize;
596 inline void Bitmap::SetPrefSize( const Size& rSize )
598 maPrefSize = rSize;
601 inline sal_Int64 Bitmap::GetSizeBytes() const
603 const auto aSizePixel = GetSizePixel();
604 const sal_Int64 aBitCount = vcl::pixelFormatBitCount(getPixelFormat());
605 sal_Int64 aSizeInBytes = (aSizePixel.Width() * aSizePixel.Height() * aBitCount) / 8;
606 return aSizeInBytes;
609 #endif // INCLUDED_VCL_BITMAP_HXX
611 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */