Arm-2D  
2D Image Processing Library for Cortex-M Processors
 
Loading...
Searching...
No Matches
arm_2d_conversion.h
1/*
2 * Copyright (C) 2022 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: Arm-2D Library
21 * Title: #include "arm_2d.h"
22 * Description: Public header file to contain the APIs for colour space
23 * conversions
24 *
25 * $Date: 29. April 2024
26 * $Revision: V.1.0.6
27 *
28 * Target Processor: Cortex-M cores
29 * -------------------------------------------------------------------- */
30
31#ifndef __ARM_2D_CONVERSION_H__
32#define __ARM_2D_CONVERSION_H__
33
34/*============================ INCLUDES ======================================*/
35
36#include "arm_2d_types.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42#if defined(__clang__)
43# pragma clang diagnostic push
44# pragma clang diagnostic ignored "-Wunknown-warning-option"
45# pragma clang diagnostic ignored "-Wreserved-identifier"
46# pragma clang diagnostic ignored "-Wdeclaration-after-statement"
47# pragma clang diagnostic ignored "-Wunknown-warning-option"
48# pragma clang diagnostic ignored "-Wreserved-identifier"
49# pragma clang diagnostic ignored "-Wsign-conversion"
50# pragma clang diagnostic ignored "-Wnarrowing"
51#elif defined(__IS_COMPILER_IAR__)
52# pragma diag_suppress=Go029
53#endif
54
55
56
57/*============================ MACROS ========================================*/
58
59/*!
60 * \addtogroup Deprecated
61 * @{
62 */
63#define arm_2dp_convert_colour_to_rgb888 arm_2dp_convert_colour_to_cccn888
64#define arm_2d_convert_colour_to_rgb888 arm_2d_convert_colour_to_cccn888
65/*! @} */
66
67
68/*!
69 * \addtogroup gConversion 6 Conversion Operations
70 * @{
71 */
72
73/*============================ MACROFIED FUNCTIONS ===========================*/
74
75#define arm_2d_convert_colour_to_gray8( __SRC_ADDR, /* source tile address */ \
76 __DES_ADDR /* target tile address */) \
77 arm_2dp_convert_colour_to_gray8(NULL, \
78 (__SRC_ADDR), \
79 (__DES_ADDR))
80
81#define arm_2d_tile_copy_to_gray8( __SRC_ADDR, /* source tile address */ \
82 __DES_ADDR, /* target tile address */ \
83 __DES_REGION) /* target region address */ \
84 arm_2dp_tile_copy_to_gray8( NULL, \
85 (__SRC_ADDR), \
86 (__DES_ADDR), \
87 (__DES_REGION))
88
89#define arm_2d_convert_colour_to_rgb565(__SRC_ADDR, /* source tile address */ \
90 __DES_ADDR /* target tile address */) \
91 arm_2dp_convert_colour_to_rgb565( NULL, \
92 (__SRC_ADDR), \
93 (__DES_ADDR))
94
95#define arm_2d_tile_copy_to_rgb565( __SRC_ADDR, /* source tile address */ \
96 __DES_ADDR, /* target tile address */ \
97 __DES_REGION) /* target region address */ \
98 arm_2dp_tile_copy_to_rgb565(NULL, \
99 (__SRC_ADDR), \
100 (__DES_ADDR), \
101 (__DES_REGION))
102
103#define arm_2d_convert_colour_to_cccn888(__SRC_ADDR, /* source tile address */ \
104 __DES_ADDR /* target tile address */) \
105 arm_2dp_convert_colour_to_cccn888( NULL, \
106 (__SRC_ADDR), \
107 (__DES_ADDR))
108
109#define arm_2d_tile_copy_to_cccn888(__SRC_ADDR, /* source tile address */ \
110 __DES_ADDR, /* target tile address */ \
111 __DES_REGION) /* target region address */ \
112 arm_2dp_tile_copy_to_cccn888( NULL, \
113 (__SRC_ADDR), \
114 (__DES_ADDR), \
115 (__DES_REGION))
116
117#define arm_2d_pixel_ccca8888_to_rgb565(__COLOUR) \
118 ({__arm_2d_color_fast_rgb_t ARM_2D_SAFE_NAME(tChannels); \
119 __arm_2d_ccca8888_unpack((__COLOUR), &ARM_2D_SAFE_NAME(tChannels)); \
120 __arm_2d_rgb565_pack(&ARM_2D_SAFE_NAME(tChannels));})
121
122#define arm_2d_pixel_ccca8888_to_gray8(__COLOUR) \
123 ({__arm_2d_color_fast_rgb_t ARM_2D_SAFE_NAME(tChannels); \
124 __arm_2d_ccca8888_unpack((__COLOUR), &ARM_2D_SAFE_NAME(tChannels)); \
125 __arm_2d_gray8_pack(&ARM_2D_SAFE_NAME(tChannels));})
126
127#define arm_2d_pixel_brga8888_to_rgb565 arm_2d_pixel_ccca8888_to_rgb565
128#define arm_2d_pixel_brga8888_to_gray8 arm_2d_pixel_ccca8888_to_gray8
129
130/*============================ TYPES =========================================*/
131
133
134/*! \brief 3x16-bit packed RGB color
135 * autovectorizer friendly format
136 */
137typedef union {
138 uint16_t BGRA[4];
139 struct {
140 uint16_t B;
141 uint16_t G;
142 uint16_t R;
143 uint16_t A;
144 };
146
147/*============================ GLOBAL VARIABLES ==============================*/
148/*============================ PROTOTYPES ====================================*/
149
150/*----------------------------------------------------------------------------*
151 * Colour channels extraction/packing *
152 *----------------------------------------------------------------------------*/
153
154/*!
155 * \brief unpack a 8bit colour into a given __arm_2d_color_fast_rgb_t object
156 * \param[in] wColour the target brga888 colour
157 * \param[in] ptRGB a __arm_2d_color_fast_rgb_t object
158 */
159ARM_NONNULL(2)
160__STATIC_INLINE void __arm_2d_gray8_unpack( uint8_t chColor,
162{
163 assert(NULL != ptRGB);
164
165 ptRGB->B = (uint16_t) chColor;
166 ptRGB->G = (uint16_t) chColor;
167 ptRGB->R = (uint16_t) chColor;
168 ptRGB->A = (uint16_t) 0xFF;
169}
170
171/*!
172 * \brief unpack a rgb565 colour into a given __arm_2d_color_fast_rgb_t object
173 * \param[in] hwColour the target rgb565 colour
174 * \param[in] ptRGB a __arm_2d_color_fast_rgb_t object
175 */
176ARM_NONNULL(2)
177__STATIC_INLINE void __arm_2d_rgb565_unpack(uint16_t hwColor,
179{
180 assert(NULL != ptRGB);
181
182 /* uses explicit extraction, leading to a more efficient autovectorized code */
183 uint16_t maskRunpk = 0x001f, maskGunpk = 0x003f;
184
185 ptRGB->B = (uint16_t) ((hwColor & maskRunpk) << 3);
186 ptRGB->R = (uint16_t) ((hwColor >> 11) << 3);
187 ptRGB->G = (uint16_t) (((hwColor >> 5) & maskGunpk) << 2);
188
189 ptRGB->A = 0xFF;
190}
191
192ARM_NONNULL(2)
193__STATIC_INLINE void __arm_2d_rgb565_unpack_comp(uint16_t hwColor,
195{
196 assert(NULL != ptRGB);
197
198 /* uses explicit extraction, leading to a more efficient autovectorized code */
199 uint16_t maskRunpk = 0x001f, maskGunpk = 0x003f;
200
201 if (hwColor) {
202 ptRGB->B = ((uint16_t) ((hwColor & maskRunpk) << 3)) | 0x7;
203 ptRGB->R = ((uint16_t) ((hwColor >> 11) << 3)) | 0x7;
204 ptRGB->G = ((uint16_t) (((hwColor >> 5) & maskGunpk)) << 2) | 0x03;
205 } else {
206 ptRGB->B = (uint16_t) ((hwColor & maskRunpk) << 3);
207 ptRGB->R = (uint16_t) ((hwColor >> 11) << 3);
208 ptRGB->G = (uint16_t) (((hwColor >> 5) & maskGunpk) << 2);
209 }
210
211 ptRGB->A = 0xFF;
212}
213
214/*!
215 * \brief unpack a 32bit colour into a given __arm_2d_color_fast_rgb_t object
216 * \param[in] wColour the target brga888 colour
217 * \param[in] ptRGB a __arm_2d_color_fast_rgb_t object
218 */
219ARM_NONNULL(2)
220__STATIC_INLINE void __arm_2d_ccca8888_unpack( uint32_t wColor,
222{
223 assert(NULL != ptRGB);
224
225 uint8_t *pchChannel = (uint8_t *)&wColor;
226
227 ptRGB->B = (uint16_t) pchChannel[0];
228 ptRGB->G = (uint16_t) pchChannel[1];
229 ptRGB->R = (uint16_t) pchChannel[2];
230 ptRGB->A = (uint16_t) pchChannel[3];
231}
232
233
234/*!
235 * \brief generate a gray8 colour from a __arm_2d_color_fast_rgb_t object
236 * \param[in] ptRGB the target __arm_2d_color_fast_rgb_t object
237 * \return uint8_t a gray8 colour
238 */
239ARM_NONNULL(1)
240__STATIC_INLINE uint8_t __arm_2d_gray8_pack(__arm_2d_color_fast_rgb_t * ptRGB)
241{
242 assert(NULL != ptRGB);
243
244 uint16_t tGrayScale = (ptRGB->R * 77 + ptRGB->G * 151 + ptRGB->B * 28) >> 8;
245
246 return (uint8_t)( (tGrayScale <= 255) * tGrayScale
247 + (tGrayScale > 255) * 255);
248}
249
250
251/*!
252 * \brief generate a rgb565 colour from a __arm_2d_color_fast_rgb_t object
253 * \param[in] ptRGB the target __arm_2d_color_fast_rgb_t object
254 * \return uint16_t a rgb565 colour
255 */
256ARM_NONNULL(1)
257__STATIC_INLINE uint16_t __arm_2d_rgb565_pack(__arm_2d_color_fast_rgb_t * ptRGB)
258{
259 assert(NULL != ptRGB);
260
261 arm_2d_color_rgb565_t tOutput = {
262 .u5B = (uint16_t) (ptRGB->B >> 3),
263 .u6G = (uint16_t) (ptRGB->G >> 2),
264 .u5R = (uint16_t) (ptRGB->R >> 3),
265 };
266 return tOutput.tValue;
267}
268
269/*!
270 * \brief generate a cccn888 colour from a __arm_2d_color_fast_rgb_t object
271 * \param[in] ptRGB the target __arm_2d_color_fast_rgb_t object
272 * \return uint32_t a cccn888 colour
273 * \note the alpha channel will be kept in the output value
274 */
275ARM_NONNULL(1)
276__STATIC_INLINE uint32_t __arm_2d_ccca888_pack(__arm_2d_color_fast_rgb_t * ptRGB)
277{
278 assert(NULL != ptRGB);
279
280 arm_2d_color_bgra8888_t tOutput = {
281 .u8B = (uint16_t) ptRGB->B,
282 .u8G = (uint16_t) ptRGB->G,
283 .u8R = (uint16_t) ptRGB->R,
284 .u8A = (uint16_t) ptRGB->A,
285 };
286 return tOutput.tValue;
287}
288
289
290/*----------------------------------------------------------------------------*
291 * Colour Conversion *
292 *----------------------------------------------------------------------------*/
293
294/*!
295 * \brief convert the colour format of a given tile to gray8
296 * \param[in] ptOP the control block, NULL means using the default control block
297 * \param[in] ptSource the source tile
298 * \param[in] ptTarget the output tile (holding a buffer)
299 * \return arm_fsm_rt_t the operation result
300 */
301extern
302ARM_NONNULL(2,3)
304 const arm_2d_tile_t *ptSource,
305 const arm_2d_tile_t *ptTarget);
306
307/*!
308 * \brief copy a given tile to a gray8 target tile
309 * \param[in] ptOP the control block, NULL means using the default control block
310 * \param[in] ptSource the source tile
311 * \param[in] ptTarget the output tile (holding a buffer)
312 * \param[in] ptRegion the target region, NULL means using the region of the
313 * target tile.
314 * \return arm_fsm_rt_t the operation result
315 */
316extern
317ARM_NONNULL(2,3)
319 const arm_2d_tile_t *ptSource,
320 const arm_2d_tile_t *ptTarget,
321 const arm_2d_region_t *ptRegion);
322
323/*!
324 * \brief convert the colour format of a given tile to rgb565
325 * \param[in] ptOP the control block, NULL means using the default control block
326 * \param[in] ptSource the source tile
327 * \param[in] ptTarget the output tile (holding a buffer)
328 * \return arm_fsm_rt_t the operation result
329 */
330extern
331ARM_NONNULL(2,3)
333 const arm_2d_tile_t *ptSource,
334 const arm_2d_tile_t *ptTarget);
335
336/*!
337 * \brief copy a given tile to a rgb565 target tile
338 * \param[in] ptOP the control block, NULL means using the default control block
339 * \param[in] ptSource the source tile
340 * \param[in] ptTarget the output tile (holding a buffer)
341 * \param[in] ptRegion the target region, NULL means using the region of the
342 * target tile.
343 * \return arm_fsm_rt_t the operation result
344 */
345extern
346ARM_NONNULL(2,3)
348 const arm_2d_tile_t *ptSource,
349 const arm_2d_tile_t *ptTarget,
350 const arm_2d_region_t *ptRegion);
351
352/*!
353 * \brief convert the colour format of a given tile to cccn888
354 * \param[in] ptOP the control block, NULL means using the default control block
355 * \param[in] ptSource the source tile
356 * \param[in] ptTarget the output tile (holding a buffer)
357 * \return arm_fsm_rt_t the operation result
358 */
359extern
360ARM_NONNULL(2,3)
362 const arm_2d_tile_t *ptSource,
363 const arm_2d_tile_t *ptTarget);
364
365/*!
366 * \brief copy a given tile to a cccn888 target tile
367 * \param[in] ptOP the control block, NULL means using the default control block
368 * \param[in] ptSource the source tile
369 * \param[in] ptTarget the output tile (holding a buffer)
370 * \param[in] ptRegion the target region, NULL means using the region of the
371 * target tile.
372 * \return arm_fsm_rt_t the operation result
373 */
374extern
375ARM_NONNULL(2,3)
377 const arm_2d_tile_t *ptSource,
378 const arm_2d_tile_t *ptTarget,
379 const arm_2d_region_t *ptRegion);
380
381/*! @} */
382
383#if defined(__clang__)
384# pragma clang diagnostic pop
385#elif defined(__IS_COMPILER_IAR__)
386# pragma diag_warning=Go029
387#endif
388
389#ifdef __cplusplus
390}
391#endif
392
393#endif