2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #ifndef DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_
19 #define DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_
22 #include <dali/integration-api/bitmap.h>
23 #include <dali/public-api/images/image-attributes.h>
36 * @brief Identify which combination of x and y dimensions matter in terminating iterative box filtering.
40 BoxDimensionTestEither,
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.
52 Integration::BitmapPtr ApplyAttributesToBitmap( Integration::BitmapPtr bitmap, const ImageAttributes& requestedAttributes );
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.
59 Integration::BitmapPtr DownscaleBitmap( Integration::Bitmap& bitmap, const ImageAttributes& requestedAttributes );
62 * @brief Destructive in-place downscaling by a power of 2 factor.
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
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.
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 );
83 * @copydoc DownscaleInPlacePow2RGB888
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 );
93 * @copydoc DownscaleInPlacePow2RGB888
95 * For the 2-byte packed 16 bit format RGB565.
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 );
105 * @copydoc DownscaleInPlacePow2RGB888
107 * For 2-byte formats such as lum8alpha8, but not packed 16 bit formats like RGB565.
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 );
117 * @copydoc DownscaleInPlacePow2RGB888
119 * For single-byte formats such as lum8 or alpha8.
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 );
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.
133 void HalveScanlineInPlaceRGB888( unsigned char * pixels, unsigned int width );
136 * @copydoc HalveScanlineInPlaceRGB888
138 void HalveScanlineInPlaceRGBA8888(
139 unsigned char * pixels,
140 unsigned int width );
143 * @copydoc HalveScanlineInPlaceRGB888
145 void HalveScanlineInPlaceRGB565( unsigned char * pixels, unsigned int width );
148 * @copydoc HalveScanlineInPlaceRGB888
150 void HalveScanlineInPlace2Bytes(
151 unsigned char * pixels,
152 unsigned int width );
155 * @copydoc HalveScanlineInPlaceRGB888
157 void HalveScanlineInPlace1Byte(
158 unsigned char * pixels,
159 unsigned int width );
162 * @brief Average pixels at corresponding offsets in two scanlines.
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.
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 );
178 * @copydoc AverageScanlines1
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 );
188 * @copydoc AverageScanlines1
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 );
198 * @copydoc AverageScanlines1
200 void AverageScanlinesRGBA8888(
201 const unsigned char * scanline1,
202 const unsigned char * scanline2,
203 unsigned char * outputScanline,
204 unsigned int width );
207 * @copydoc AverageScanlines1
209 void AverageScanlinesRGB565(
210 const unsigned char * scanline1,
211 const unsigned char * scanline2,
212 unsigned char* outputScanline,
213 unsigned int width );
216 * @brief Inline functions exposed in header to allow unit testing.
221 * @brief Average two integer arguments.
222 * @return The average of two uint arguments.
223 * @param[in] a First component to average.
224 * @param[in] b Second component to average.
226 inline unsigned int AverageComponent( unsigned int a, unsigned int b )
228 unsigned int avg = (a + b) >> 1u;
233 * @brief Average a pair of RGB565 pixels.
234 * @return The average of two RGBA8888 pixels.
235 * @param[in] a First pixel to average.
236 * @param[in] b Second pixel to average
238 inline uint32_t AveragePixelRGBA8888( uint32_t a, uint32_t b )
240 const unsigned int avg =
241 ((AverageComponent( (a & 0xff000000) >> 1u, (b & 0xff000000) >> 1u ) << 1u) & 0xff000000 ) +
242 (AverageComponent( a & 0x00ff0000, b & 0x00ff0000 ) & 0x00ff0000 ) +
243 (AverageComponent( a & 0x0000ff00, b & 0x0000ff00 ) & 0x0000ff00 ) +
244 (AverageComponent( a & 0x000000ff, b & 0x000000ff ) );
246 ///@ToDo: Optimise by trying return (((a ^ b) & 0xfefefefeUL) >> 1) + (a & b);
247 ///@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.
251 * @brief Average a pair of RGB565 pixels.
252 * @param a[in] Low 16 bits hold a color value as RGB565 to average with parameter b.
253 * @param b[in] Low 16 bits hold a color value as RGB565 to average with parameter a.
254 * @return The average color of the two RGB565 pixels passed in, in the low 16 bits of the returned value.
256 inline uint32_t AveragePixelRGB565( uint32_t a, uint32_t b )
258 const unsigned int avg =
259 (AverageComponent( a & 0xf800, b & 0xf800 ) & 0xf800 ) +
260 (AverageComponent( a & 0x7e0, b & 0x7e0 ) & 0x7e0 ) +
261 (AverageComponent( a & 0x1f, b & 0x1f ) );
265 } // namespace - unnamed
266 } /* namespace Platform */
267 } /* namespace Internal */
268 } /* namespace Dali */
270 #endif /* DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_ */