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