Merge "Recover PixmapImage::GetPixmap() without any parameters (no build break)"...
[platform/core/uifw/dali-adaptor.git] / platform-abstractions / portable / image-operations.h
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #ifndef DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_
19 #define DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/bitmap.h>
23 #include <dali/public-api/images/image-attributes.h>
24
25 // EXTERNAL INCLUDES
26 #include <stdint.h>
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 namespace Platform
33 {
34
35 /**
36  * @brief Identify which combination of x and y dimensions matter in terminating iterative box filtering.
37  */
38 enum BoxDimensionTest
39 {
40   BoxDimensionTestEither,
41   BoxDimensionTestBoth,
42   BoxDimensionTestX,
43   BoxDimensionTestY
44 };
45
46 /**
47  * @brief Apply requested attributes to bitmap.
48  * @param[in] bitmap The input bitmap.
49  * @param[in] requestedAttributes Attributes which should be applied to bitmap.
50  * @return A bitmap which results from applying the requested attributes to the bitmap passed-in, or the original bitmap passed in if the attributes have no effect.
51  */
52 Integration::BitmapPtr ApplyAttributesToBitmap( Integration::BitmapPtr bitmap, const ImageAttributes& requestedAttributes );
53
54 /**
55  * @brief Apply downscaling to a bitmap according to requested attributes.
56  * @note Only rough power of 2 box filtering is currently performed.
57  * @note The input bitmap may be modified and left in an invalid state so must be discarded.
58  **/
59 Integration::BitmapPtr DownscaleBitmap( Integration::Bitmap& bitmap, const ImageAttributes& requestedAttributes );
60
61 /**
62  * @brief Destructive in-place downscaling by a power of 2 factor.
63  *
64  * A box filter with a 2x2 kernel is repeatedly applied as long as the result
65  * of the next downscaling step would not be smaller than the desired
66  * dimensions.
67  * @param[in,out] pixels The buffer both to read from and write the result to.
68  * @param[in]     inputWidth The width of the input image.
69  * @param[in]     inputHeight The height of the input image.
70  * @param[in]     desiredWidth The width the client is requesting.
71  * @param[in]     desiredHeight The height the client is requesting.
72  * @param[out]    outWidth  The resulting width after downscaling.
73  * @param[out]    outHeight The resulting height after downscaling.
74  */
75 void DownscaleInPlacePow2RGB888(
76     unsigned char * pixels,
77     unsigned int inputWidth, unsigned int inputHeight,
78     unsigned int desiredWidth, unsigned int desiredHeight,
79     BoxDimensionTest dimensionTest,
80     unsigned int& outWidth, unsigned int& outHeight );
81
82 /**
83  * @copydoc DownscaleInPlacePow2RGB888
84  */
85 void DownscaleInPlacePow2RGBA8888(
86     unsigned char * pixels,
87     unsigned int inputWidth, unsigned int inputHeight,
88     unsigned int desiredWidth, unsigned int desiredHeight,
89     BoxDimensionTest dimensionTest,
90     unsigned int& outWidth, unsigned int& outHeight );
91
92 /**
93  * @copydoc DownscaleInPlacePow2RGB888
94  *
95  * For the 2-byte packed 16 bit format RGB565.
96  */
97 void DownscaleInPlacePow2RGB565(
98     unsigned char * pixels,
99     unsigned int inputWidth, unsigned int inputHeight,
100     unsigned int desiredWidth, unsigned int desiredHeight,
101     BoxDimensionTest dimensionTest,
102     unsigned int& outWidth, unsigned int& outHeight );
103
104 /**
105  * @copydoc DownscaleInPlacePow2RGB888
106  *
107  * For 2-byte formats such as lum8alpha8, but not packed 16 bit formats like RGB565.
108  */
109 void DownscaleInPlacePow2ComponentPair(
110     unsigned char * pixels,
111     unsigned int inputWidth, unsigned int inputHeight,
112     unsigned int desiredWidth, unsigned int desiredHeight,
113     BoxDimensionTest dimensionTest,
114     unsigned int& outWidth, unsigned int& outHeight );
115
116 /**
117  * @copydoc DownscaleInPlacePow2RGB888
118  *
119  * For single-byte formats such as lum8 or alpha8.
120  */
121 void DownscaleInPlacePow2SingleBytePerPixel(
122     unsigned char * pixels,
123     unsigned int inputWidth, unsigned int inputHeight,
124     unsigned int desiredWidth, unsigned int desiredHeight,
125     BoxDimensionTest dimensionTest,
126     unsigned int& outWidth, unsigned int& outHeight );
127
128 /**
129  * @brief Average adjacent pairs of pixels, overwriting the input array.
130  * @param[in,out] pixels The array of pixels to work on.
131  * @param[i]      width  The number of pixels in the array passed-in.
132  */
133 void HalveScanlineInPlaceRGB888( unsigned char * pixels, unsigned int width );
134
135 /**
136  * @copydoc HalveScanlineInPlaceRGB888
137  */
138 void HalveScanlineInPlaceRGBA8888(
139     unsigned char * pixels,
140     unsigned int width );
141
142 /**
143  * @copydoc HalveScanlineInPlaceRGB888
144  */
145 void HalveScanlineInPlaceRGB565( unsigned char * pixels, unsigned int width );
146
147 /**
148  * @copydoc HalveScanlineInPlaceRGB888
149  */
150 void HalveScanlineInPlace2Bytes(
151     unsigned char * pixels,
152     unsigned int width );
153
154 /**
155  * @copydoc HalveScanlineInPlaceRGB888
156  */
157 void HalveScanlineInPlace1Byte(
158     unsigned char * pixels,
159     unsigned int width );
160
161 /**
162  * @brief Average pixels at corresponding offsets in two scanlines.
163  *
164  * outputScanline is allowed to alias scanline1.
165  * @param[in] scanline1 First scanline of pixels to average.
166  * @param[in] scanline2 Second scanline of pixels to average.
167  * @param[out] outputScanline Destination for the averaged pixels.
168  * @param[in] width The widths of all the scanlines passed-in.
169  */
170 void AverageScanlines1(
171     const unsigned char * scanline1,
172     const unsigned char * scanline2,
173     unsigned char* outputScanline,
174     /** Image width in pixels (1 byte == 1 pixel: e.g. lum8 or alpha8).*/
175     unsigned int width );
176
177 /**
178  * @copydoc AverageScanlines1
179  */
180 void AverageScanlines2(
181     const unsigned char * scanline1,
182     const unsigned char * scanline2,
183     unsigned char* outputScanline,
184     /** Image width in pixels (2 bytes == 1 pixel: e.g. lum8alpha8).*/
185     unsigned int width );
186
187 /**
188  * @copydoc AverageScanlines1
189  */
190 void AverageScanlines3(
191     const unsigned char * scanline1,
192     const unsigned char * scanline2,
193     unsigned char* outputScanline,
194     /** Image width in pixels (3 bytes == 1 pixel: e.g. RGB888).*/
195     unsigned int width );
196
197 /**
198  * @copydoc AverageScanlines1
199  */
200 void AverageScanlinesRGBA8888(
201     const unsigned char * scanline1,
202     const unsigned char * scanline2,
203     unsigned char * outputScanline,
204     unsigned int width );
205
206 /**
207  * @copydoc AverageScanlines1
208  */
209 void AverageScanlinesRGB565(
210     const unsigned char * scanline1,
211     const unsigned char * scanline2,
212     unsigned char* outputScanline,
213     unsigned int width );
214
215 /**
216  * @brief Inline functions exposed in header to allow unit testing.
217  */
218 /**
219  * @brief Average two integer arguments.
220  * @return The average of two uint arguments.
221  * @param[in] a First component to average.
222  * @param[in] b Second component to average.
223  **/
224 inline unsigned int AverageComponent( unsigned int a, unsigned int b )
225 {
226   unsigned int avg = (a + b) >> 1u;
227   return avg;
228 }
229
230 /**
231  * @brief Average a pair of RGB565 pixels.
232  * @return The average of two RGBA8888 pixels.
233  * @param[in] a First pixel to average.
234  * @param[in] b Second pixel to average
235  **/
236 inline uint32_t AveragePixelRGBA8888( uint32_t a, uint32_t b )
237 {
238   const unsigned int avg =
239     ((AverageComponent( (a & 0xff000000) >> 1u, (b & 0xff000000) >> 1u ) << 1u) & 0xff000000 ) +
240     (AverageComponent( a & 0x00ff0000, b & 0x00ff0000 ) & 0x00ff0000 ) +
241     (AverageComponent( a & 0x0000ff00, b & 0x0000ff00 ) & 0x0000ff00 ) +
242     (AverageComponent( a & 0x000000ff, b & 0x000000ff ) );
243   return avg;
244   ///@ToDo: Optimise by trying return (((a ^ b) & 0xfefefefeUL) >> 1) + (a & b);
245   ///@ToDo: Optimise for ARM using the single ARMV6 instruction: UHADD8  R4, R0, R5. This is not Neon. It runs in the normal integer pipeline so there is no downside like a stall moving between integer and copro.
246 }
247
248 /**
249  * @brief Average a pair of RGB565 pixels.
250  * @param a[in] Low 16 bits hold a color value as RGB565 to average with parameter b.
251  * @param b[in] Low 16 bits hold a color value as RGB565 to average with parameter a.
252  * @return The average color of the two RGB565 pixels passed in, in the low 16 bits of the returned value.
253  **/
254 inline uint32_t AveragePixelRGB565( uint32_t a, uint32_t b )
255 {
256   const unsigned int avg =
257     (AverageComponent( a & 0xf800, b & 0xf800 ) & 0xf800 ) +
258     (AverageComponent( a & 0x7e0,  b & 0x7e0 )  & 0x7e0 ) +
259     (AverageComponent( a & 0x1f,   b & 0x1f ) );
260   return avg;
261 }
262
263 } /* namespace Platform */
264 } /* namespace Internal */
265 } /* namespace Dali */
266
267 #endif /* DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_ */