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