Merge "Make PixelData flag that we release buffer after texture upload" into devel...
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / common / pixel-buffer-impl.h
1 #ifndef DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H
2 #define DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H
3
4 /*
5  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * 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, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/public-api/images/image-operations.h> // For ImageDimensions
25 #include <dali/public-api/images/pixel-data.h>
26 #include <dali/public-api/object/base-object.h>
27 #include <dali/public-api/object/property-map.h>
28
29 // EXTERNAL INCLUDES
30 #include <memory>
31
32 namespace Dali
33 {
34 namespace Internal
35 {
36 namespace Adaptor
37 {
38 class PixelBuffer;
39 typedef IntrusivePtr<PixelBuffer> PixelBufferPtr;
40
41 class PixelBuffer : public BaseObject
42 {
43 public:
44   /**
45    * @brief Create a PixelBuffer object with a pre-allocated buffer.
46    * The PixelBuffer object owns this buffer, which may be retrieved
47    * and modified using GetBuffer().
48    *
49    * @param [in] width            Buffer width in pixels
50    * @param [in] height           Buffer height in pixels
51    * @param [in] pixelFormat      The pixel format
52    */
53   static PixelBufferPtr New(uint32_t      width,
54                             uint32_t      height,
55                             Pixel::Format pixelFormat);
56
57   /**
58    * @brief Create a PixelBuffer object. For internal use only.
59    *
60    * @param [in] buffer           The raw pixel data.
61    * @param [in] bufferSize       The size of the buffer in bytes
62    * @param [in] width            Buffer width in pixels
63    * @param [in] height           Buffer height in pixels
64    * @param [in] stride           Buffer stride in pixels, 0 means the buffer is tightly packed
65    * @param [in] pixelFormat      The pixel format
66    */
67   static PixelBufferPtr New(uint8_t*      buffer,
68                             uint32_t      bufferSize,
69                             uint32_t      width,
70                             uint32_t      height,
71                             uint32_t      stride,
72                             Pixel::Format pixelFormat);
73
74   /**
75    * Convert a pixelBuffer object into a PixelData object.
76    * The new object takes ownership of the buffer data, and the
77    * mBuffer pointer is reset to NULL.
78    * @param[in] pixelBuffer The buffer to convert
79    * @param[in] releaseAfterUpload Whether converted PixelData released after upload or not.
80    * @return the pixelData
81    */
82   static Dali::PixelData Convert(PixelBuffer& pixelBuffer, bool releaseAfterUpload);
83
84   /**
85    * @brief Constructor.
86    *
87    * @param [in] buffer           The raw pixel data.
88    * @param [in] bufferSize       The size of the buffer in bytes
89    * @param [in] width            Buffer width in pixels
90    * @param [in] height           Buffer height in pixels
91    * @param [in] stride           Buffer stride in pixels, 0 means the buffer is tightly packed
92    * @param [in] pixelFormat      The pixel format
93    */
94   PixelBuffer(uint8_t*      buffer,
95               uint32_t      bufferSize,
96               uint32_t      width,
97               uint32_t      height,
98               uint32_t      stride,
99               Pixel::Format pixelFormat);
100
101 protected:
102   /**
103    * @brief Destructor.
104    *
105    * Release the pixel buffer if exists.
106    */
107   ~PixelBuffer() override;
108
109 public:
110   /**
111    * Get the total allocated size of current pixel buffers
112    */
113   static uint32_t GetTotalAllocatedSize()
114   {
115 #if defined(DEBUG_ENABLED)
116     return gPixelBufferAllocationTotal;
117 #else
118     return 0;
119 #endif
120   }
121
122   /**
123    * Get the width of the buffer in pixels.
124    * @return The width of the buffer in pixels
125    */
126   uint32_t GetWidth() const;
127
128   /**
129    * Get the height of the buffer in pixels
130    * @return The height of the buffer in pixels
131    */
132   uint32_t GetHeight() const;
133
134   /**
135    * @brief Gets the stride of the buffer in pixels.
136    * @return The stride of the buffer in pixels. 0 means the buffer is tightly packed.
137    */
138   uint32_t GetStride() const;
139
140   /**
141    * Get the pixel format
142    * @return The pixel format
143    */
144   Pixel::Format GetPixelFormat() const;
145
146   /**
147    * Get the pixel buffer if it's present.
148    * @return The buffer if exists, or NULL if there is no pixel buffer.
149    */
150   uint8_t* GetBuffer() const;
151
152   /**
153    * @copydoc Devel::PixelBuffer::GetBuffer()
154    */
155   const uint8_t* GetConstBuffer() const;
156
157   /**
158    * Get the size of the buffer in bytes
159    * @return The size of the buffer
160    */
161   uint32_t GetBufferSize() const;
162
163   /**
164    * Copy the buffer into a new PixelData
165    */
166   Dali::PixelData CreatePixelData() const;
167
168   /**
169    * @brief Apply the mask to the current buffer.
170    *
171    * This method may update the internal object - e.g. the new buffer
172    * may have a different pixel format - as an alpha channel may be
173    * added.
174    * @param[in] mask The mask to apply to this pixel buffer
175    * @param[in] contentScale The scaling factor to apply to the content
176    * @param[in] cropToMask Whether to crop the output to the mask size (true) or scale the
177    * mask to the content size (false)
178    */
179   void ApplyMask(const PixelBuffer& mask, float contentScale, bool cropToMask);
180
181   /**
182    * @brief Apply a Gaussian blur to the current buffer with the given radius.
183    *
184    * @param[in] blurRadius The radius for Gaussian blur
185    */
186   void ApplyGaussianBlur(const float blurRadius);
187
188   /**
189    * Crops this buffer to the given crop rectangle. Assumes the crop rectangle
190    * is within the bounds of this size.
191    * @param[in] x The top left corner's X
192    * @param[in] y The top left corner's y
193    * @param[in] cropDimensions The dimensions of the crop
194    */
195   void Crop(uint16_t x, uint16_t y, ImageDimensions cropDimensions);
196
197   /**
198    * Resizes the buffer to the given dimensions. Uses either Lanczos4 for downscaling
199    * or Mitchell for upscaling
200    * @param[in] outDimensions The new dimensions
201    */
202   void Resize(ImageDimensions outDimensions);
203
204   /**
205    * Multiplies the image's color values by the alpha value. This provides better
206    * blending capability.
207    */
208   void MultiplyColorByAlpha();
209
210   /**
211    * @brief Sets image metadata
212    *
213    * @param map Property map containing Exif fields
214    */
215   void SetMetadata(const Property::Map& map);
216
217   /**
218    * @brief Returns image metadata as a property map
219    * @param[out] outMetadata Property map to copy the data into
220    * @return True on success
221    */
222   bool GetMetadata(Property::Map& outMetadata) const;
223
224   /**
225    * @brief Sets metadata property map for the pixel buffer
226    * @note The function takes over the ownership of the property map
227    * @param[in] metadata Property map to copy the data into
228    */
229   void SetMetadata(std::unique_ptr<Property::Map> metadata);
230
231   /**
232    * Allocates fixed amount of memory for the pixel data. Used by compressed formats.
233    * @param[in] size Size of memory to be allocated
234    */
235   void AllocateFixedSize(uint32_t size);
236
237   /**
238    * @copydoc Devel::PixelBuffer::Rotate()
239    */
240   bool Rotate(Degree angle);
241
242   /**
243    * @copydoc Devel::PixelBuffer::IsAlphaPreMultiplied()
244    */
245   bool IsAlphaPreMultiplied() const;
246
247   /**
248    * @copydoc Devel::PixelBuffer::GetBrightness()
249    */
250   uint32_t GetBrightness() const;
251
252 private:
253   /*
254    * Undefined copy constructor.
255    */
256   PixelBuffer(const PixelBuffer& other);
257
258   /*
259    * Undefined assignment operator.
260    */
261   PixelBuffer& operator=(const PixelBuffer& other);
262
263   /**
264    * Internal method to apply the mask to this buffer. Expects that they are the same size.
265    */
266   void ApplyMaskInternal(const PixelBuffer& mask);
267
268   /**
269    * Takes ownership of the other object's pixel buffer.
270    */
271   void TakeOwnershipOfBuffer(PixelBuffer& pixelBuffer);
272
273   /**
274    * Release the buffer
275    */
276   void ReleaseBuffer();
277
278   /**
279    * Scales this buffer buffer by the given factor, and crops at the center to the
280    * given dimensions.
281    */
282   void ScaleAndCrop(float scaleFactor, ImageDimensions cropDimensions);
283
284   /**
285    * Creates a new buffer which is a crop of the passed in buffer,
286    * using the given crop rectangle. Assumes the crop rectangle is
287    * within the bounds of this size.
288    * @param[in] inBuffer The source buffer
289    * @param[in] x The top left corner's X
290    * @param[in] y The top left corner's y
291    * @param[in] cropDimensions The dimensions of the crop
292    * @return the new pixel buffer
293    */
294   static PixelBufferPtr NewCrop(const PixelBuffer& inBuffer, uint16_t x, uint16_t y, ImageDimensions cropDimensions);
295
296   /**
297    * Creates a new buffer which is a resized version of the passed in buffer.
298    * Uses either Lanczos4 for downscaling, or Mitchell for upscaling.
299    * @param[in] inBuffer The source buffer
300    * @param[in] outDimensions The new dimensions
301    * @return a new buffer of the given size.
302    */
303   static PixelBufferPtr NewResize(const PixelBuffer& inBuffer, ImageDimensions outDimensions);
304
305 private:
306   std::unique_ptr<Property::Map> mMetadata;      ///< Metadata fields
307   uint8_t*                       mBuffer;        ///< The raw pixel data
308   uint32_t                       mBufferSize;    ///< Buffer sized in bytes
309   uint32_t                       mWidth;         ///< Buffer width in pixels
310   uint32_t                       mHeight;        ///< Buffer height in pixels
311   uint32_t                       mStride;        ///< Buffer stride in bytes, 0 means the buffer is tightly packed
312   Pixel::Format                  mPixelFormat;   ///< Pixel format
313   bool                           mPreMultiplied; ///< PreMultiplied
314
315 #if defined(DEBUG_ENABLED)
316   static uint32_t gPixelBufferAllocationTotal;
317 #endif
318 };
319
320 } // namespace Adaptor
321
322 } // namespace Internal
323
324 /**
325  * Helper methods for public API
326  */
327 inline Internal::Adaptor::PixelBuffer& GetImplementation(Devel::PixelBuffer& handle)
328 {
329   DALI_ASSERT_ALWAYS(handle && "handle is empty");
330
331   BaseObject& object = handle.GetBaseObject();
332
333   return static_cast<Internal::Adaptor::PixelBuffer&>(object);
334 }
335
336 inline const Internal::Adaptor::PixelBuffer& GetImplementation(const Devel::PixelBuffer& handle)
337 {
338   DALI_ASSERT_ALWAYS(handle && "handle is empty");
339
340   const BaseObject& object = handle.GetBaseObject();
341
342   return static_cast<const Internal::Adaptor::PixelBuffer&>(object);
343 }
344
345 } // namespace Dali
346
347 #endif // DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H