1 /*
2  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
3  * Authors:
4  *  PutinLee <putin.lee@rock-chips.com>
5  *  Cerf Yu <cerf.yu@rock-chips.com>
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 #ifndef _im2d_h_
21 #define _im2d_h_
22 
23 #include "securec.h"
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #ifndef IM_API
29 #define IM_API /* define API export as needed */
30 #endif
31 
32 typedef enum {
33     /* Rotation */
34     IM_HAL_TRANSFORM_ROT_90 = 1 << 0,
35     IM_HAL_TRANSFORM_ROT_180 = 1 << 1,
36     IM_HAL_TRANSFORM_ROT_270 = 1 << 2,
37     IM_HAL_TRANSFORM_FLIP_H = 1 << 3,
38     IM_HAL_TRANSFORM_FLIP_V = 1 << 4,
39     IM_HAL_TRANSFORM_FLIP_H_V = 1 << 5,
40     IM_HAL_TRANSFORM_MASK = 0x3f,
41 
42     /*
43      * Blend
44      * Additional blend usage, can be used with both source and target configs.
45      * If none of the below is set, the default "SRC over DST" is applied.
46      */
47     IM_ALPHA_BLEND_SRC_OVER = 1 << 6,  /* Default, Porter-Duff "SRC over DST" */
48     IM_ALPHA_BLEND_SRC = 1 << 7,       /* Porter-Duff "SRC" */
49     IM_ALPHA_BLEND_DST = 1 << 8,       /* Porter-Duff "DST" */
50     IM_ALPHA_BLEND_SRC_IN = 1 << 9,    /* Porter-Duff "SRC in DST" */
51     IM_ALPHA_BLEND_DST_IN = 1 << 10,   /* Porter-Duff "DST in SRC" */
52     IM_ALPHA_BLEND_SRC_OUT = 1 << 11,  /* Porter-Duff "SRC out DST" */
53     IM_ALPHA_BLEND_DST_OUT = 1 << 12,  /* Porter-Duff "DST out SRC" */
54     IM_ALPHA_BLEND_DST_OVER = 1 << 13, /* Porter-Duff "DST over SRC" */
55     IM_ALPHA_BLEND_SRC_ATOP = 1 << 14, /* Porter-Duff "SRC ATOP" */
56     IM_ALPHA_BLEND_DST_ATOP = 1 << 15, /* Porter-Duff "DST ATOP" */
57     IM_ALPHA_BLEND_XOR = 1 << 16,      /* Xor */
58     IM_ALPHA_BLEND_MASK = 0x1ffc0,
59 
60     IM_ALPHA_COLORKEY_NORMAL = 1 << 17,
61     IM_ALPHA_COLORKEY_INVERTED = 1 << 18,
62     IM_ALPHA_COLORKEY_MASK = 0x60000,
63 
64     IM_SYNC = 1 << 19,
65     IM_ASYNC = 1 << 26,
66     IM_CROP = 1 << 20, /* Unused */
67     IM_COLOR_FILL = 1 << 21,
68     IM_COLOR_PALETTE = 1 << 22,
69     IM_NN_QUANTIZE = 1 << 23,
70     IM_ROP = 1 << 24,
71     IM_ALPHA_BLEND_PRE_MUL = 1 << 25,
72 } IM_USAGE;
73 
74 typedef enum {
75     IM_ROP_AND = 0x88,
76     IM_ROP_OR = 0xee,
77     IM_ROP_NOT_DST = 0x55,
78     IM_ROP_NOT_SRC = 0x33,
79     IM_ROP_XOR = 0xf6,
80     IM_ROP_NOT_XOR = 0xf9,
81 } IM_ROP_CODE;
82 
83 typedef enum {
84     IM_RGA_SUPPORT_FORMAT_ERROR_INDEX = 0,
85     IM_RGA_SUPPORT_FORMAT_RGB_INDEX,
86     IM_RGA_SUPPORT_FORMAT_RGB_OTHER_INDEX,
87     IM_RGA_SUPPORT_FORMAT_BPP_INDEX,
88     IM_RGA_SUPPORT_FORMAT_YUV_8_INDEX,
89     IM_RGA_SUPPORT_FORMAT_YUV_10_INDEX,
90     IM_RGA_SUPPORT_FORMAT_YUYV_420_INDEX,
91     IM_RGA_SUPPORT_FORMAT_YUYV_422_INDEX,
92     IM_RGA_SUPPORT_FORMAT_YUV_400_INDEX,
93     IM_RGA_SUPPORT_FORMAT_Y4_INDEX,
94     IM_RGA_SUPPORT_FORMAT_MASK_INDEX,
95 } IM_RGA_SUPPORT_FORMAT_INDEX;
96 
97 typedef enum {
98     IM_RGA_SUPPORT_FORMAT_ERROR = 1 << IM_RGA_SUPPORT_FORMAT_ERROR_INDEX,
99     IM_RGA_SUPPORT_FORMAT_RGB = 1 << IM_RGA_SUPPORT_FORMAT_RGB_INDEX,
100     IM_RGA_SUPPORT_FORMAT_RGB_OTHER = 1 << IM_RGA_SUPPORT_FORMAT_RGB_OTHER_INDEX,
101     IM_RGA_SUPPORT_FORMAT_BPP = 1 << IM_RGA_SUPPORT_FORMAT_BPP_INDEX,
102     IM_RGA_SUPPORT_FORMAT_YUV_8 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_8_INDEX,
103     IM_RGA_SUPPORT_FORMAT_YUV_10 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_10_INDEX,
104     IM_RGA_SUPPORT_FORMAT_YUYV_420 = 1 << IM_RGA_SUPPORT_FORMAT_YUYV_420_INDEX,
105     IM_RGA_SUPPORT_FORMAT_YUYV_422 = 1 << IM_RGA_SUPPORT_FORMAT_YUYV_422_INDEX,
106     IM_RGA_SUPPORT_FORMAT_YUV_400 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_400_INDEX,
107     IM_RGA_SUPPORT_FORMAT_Y4 = 1 << IM_RGA_SUPPORT_FORMAT_Y4_INDEX,
108     IM_RGA_SUPPORT_FORMAT_MASK = ~((~(unsigned int)0x0 << IM_RGA_SUPPORT_FORMAT_MASK_INDEX) | 1),
109 } IM_RGA_SUPPORT_FORMAT;
110 
111 typedef enum {
112     IM_RGA_SUPPORT_FEATURE_ERROR_INDEX = 0,
113     IM_RGA_SUPPORT_FEATURE_COLOR_FILL_INDEX,
114     IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE_INDEX,
115     IM_RGA_SUPPORT_FEATURE_ROP_INDEX,
116     IM_RGA_SUPPORT_FEATURE_QUANTIZE_INDEX,
117     IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC_INDEX,
118     IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC_INDEX,
119     IM_RGA_SUPPORT_FEATURE_MASK_INDEX,
120 } IM_RGA_SUPPORT_FEATURE_INDEX;
121 
122 typedef enum {
123     IM_RGA_SUPPORT_FEATURE_ERROR = 1 << IM_RGA_SUPPORT_FEATURE_ERROR_INDEX,
124     IM_RGA_SUPPORT_FEATURE_COLOR_FILL = 1 << IM_RGA_SUPPORT_FEATURE_COLOR_FILL_INDEX,
125     IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE = 1 << IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE_INDEX,
126     IM_RGA_SUPPORT_FEATURE_ROP = 1 << IM_RGA_SUPPORT_FEATURE_ROP_INDEX,
127     IM_RGA_SUPPORT_FEATURE_QUANTIZE = 1 << IM_RGA_SUPPORT_FEATURE_QUANTIZE_INDEX,
128     IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC = 1 << IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC_INDEX,
129     IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC = 1 << IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC_INDEX,
130     IM_RGA_SUPPORT_FEATURE_MASK = ~((~(unsigned int)0x0 << IM_RGA_SUPPORT_FEATURE_MASK_INDEX) | 1),
131 } IM_RGA_SUPPORT_FEATURE;
132 
133 /* Status codes, returned by any blit function */
134 typedef enum {
135     IM_STATUS_NOERROR = 2,
136     IM_STATUS_SUCCESS = 1,
137     IM_STATUS_NOT_SUPPORTED = -1,
138     IM_STATUS_OUT_OF_MEMORY = -2,
139     IM_STATUS_INVALID_PARAM = -3,
140     IM_STATUS_ILLEGAL_PARAM = -4,
141     IM_STATUS_FAILED = 0,
142 } IM_STATUS;
143 
144 /* Status codes, returned by any blit function */
145 typedef enum {
146     IM_YUV_TO_RGB_BT601_LIMIT = 1 << 0,
147     IM_YUV_TO_RGB_BT601_FULL = 2 << 0,
148     IM_YUV_TO_RGB_BT709_LIMIT = 3 << 0,
149     IM_YUV_TO_RGB_MASK = 3 << 0,
150     IM_RGB_TO_YUV_BT601_FULL = 1 << 2,
151     IM_RGB_TO_YUV_BT601_LIMIT = 2 << 2,
152     IM_RGB_TO_YUV_BT709_LIMIT = 3 << 2,
153     IM_RGB_TO_YUV_MASK = 3 << 2,
154     IM_RGB_TO_Y4 = 1 << 4,
155     IM_RGB_TO_Y4_DITHER = 2 << 4,
156     IM_RGB_TO_Y1_DITHER = 3 << 4,
157     IM_Y4_MASK = 3 << 4,
158     IM_RGB_FULL = 1 << 8,
159     IM_RGB_CLIP = 2 << 8,
160     IM_YUV_BT601_LIMIT_RANGE = 3 << 8,
161     IM_YUV_BT601_FULL_RANGE = 4 << 8,
162     IM_YUV_BT709_LIMIT_RANGE = 5 << 8,
163     IM_YUV_BT709_FULL_RANGE = 6 << 8,
164     IM_FULL_CSC_MASK = 0xf << 8,
165     IM_COLOR_SPACE_DEFAULT = 0,
166 } IM_COLOR_SPACE_MODE;
167 
168 typedef enum {
169     IM_UP_SCALE,
170     IM_DOWN_SCALE,
171 } IM_SCALE;
172 
173 typedef enum {
174     INTER_NEAREST,
175     INTER_LINEAR,
176     INTER_CUBIC,
177 } IM_SCALE_MODE;
178 
179 /* Get RGA basic information index */
180 typedef enum {
181     RGA_VENDOR = 0,
182     RGA_VERSION,
183     RGA_MAX_INPUT,
184     RGA_MAX_OUTPUT,
185     RGA_SCALE_LIMIT,
186     RGA_INPUT_FORMAT,
187     RGA_OUTPUT_FORMAT,
188     RGA_FEATURE,
189     RGA_EXPECTED,
190     RGA_ALL,
191 } IM_INFORMATION;
192 
193 /* rga version index */
194 typedef enum {
195     RGA_V_ERR = 0x0,
196     RGA_1 = 0x1,
197     RGA_1_PLUS = 0x2,
198     RGA_2 = 0x3,
199     RGA_2_LITE0 = 0x4,
200     RGA_2_LITE1 = 0x5,
201     RGA_2_ENHANCE = 0x6,
202 } RGA_VERSION_NUM;
203 
204 typedef struct {
205     RGA_VERSION_NUM version;
206     unsigned int input_resolution;
207     unsigned int output_resolution;
208     unsigned int scale_limit;
209     unsigned int performance;
210     unsigned int input_format;
211     unsigned int output_format;
212     unsigned int feature;
213     char reserved[28];
214 } rga_info_table_entry;
215 
216 /* Rectangle definition */
217 typedef struct {
218     int x;      /* upper-left x */
219     int y;      /* upper-left y */
220     int width;  /* width */
221     int height; /* height */
222 } im_rect;
223 
224 typedef struct {
225     int max; /* The Maximum value of the color key */
226     int min; /* The minimum value of the color key */
227 } im_colorkey_range;
228 
229 typedef struct im_nn {
230     int scale_r;  /* scaling factor on R channal */
231     int scale_g;  /* scaling factor on G channal */
232     int scale_b;  /* scaling factor on B channal */
233     int offset_r; /* offset on R channal */
234     int offset_g; /* offset on G channal */
235     int offset_b; /* offset on B channal */
236 } im_nn_t;
237 
238 /* im_info definition */
239 typedef struct {
240     void *vir_addr;                   /* virtual address */
241     void *phy_addr;                   /* physical address */
242     int fd;                           /* shared fd */
243     int width;                        /* width */
244     int height;                       /* height */
245     int wstride;                      /* wstride */
246     int hstride;                      /* hstride */
247     int format;                       /* format */
248     int color_space_mode;             /* color_space_mode */
249     int color;                        /* color, used by color fill */
250     int global_alpha;                 /* global_alpha */
251     im_colorkey_range colorkey_range; /* range value of color key */
252     im_nn_t nn;
253     int rop_code;
254 } rga_buffer_t;
255 
256 /*
257  * @return error message string
258  */
259 #define imStrError(...)                                                                                                \
260     ( {                                                                                                                \
261         const char *err;                                                                                               \
262         int args[] = {__VA_ARGS__};                                                                                    \
263         int argc = sizeof(args) / sizeof(int);                                                                         \
264         if (argc == 0) {                                                                                               \
265             err = imStrError_t(IM_STATUS_INVALID_PARAM);                                                               \
266         } else if (argc == 1) {                                                                                        \
267             err = imStrError_t((IM_STATUS)args[0]);                                                                    \
268         } else {                                                                                                       \
269             err = ("Fatal error, imStrError() too many parameters\n");                                                 \
270             printf("Fatal error, imStrError() too many parameters\n");                                                 \
271         }                                                                                                              \
272         err;                                                                                                           \
273     })
274 IM_API const char *imStrError_t(IM_STATUS status);
275 
276 /*
277  * @return rga_buffer_t
278  */
279 #define wrapbuffer_virtualaddr(vir_addr, width, height, format, ...)                                                   \
280     ( {                                                                                                                \
281         rga_buffer_t buffer;                                                                                           \
282         int args[] = {__VA_ARGS__};                                                                                    \
283         int argc = sizeof(args) / sizeof(int);                                                                         \
284         if (argc == 0) {                                                                                               \
285             buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, width, height, format);                         \
286         } else if (argc == 2) {                                                                                        \
287             buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, args[0], args[1], format);                      \
288         } else {                                                                                                       \
289             printf("invalid parameter\n");                                                                             \
290         }                                                                                                              \
291         buffer;                                                                                                        \
292     })
293 
294 #define wrapbuffer_physicaladdr(phy_addr, width, height, format, ...)                                                  \
295     ( {                                                                                                                \
296         rga_buffer_t buffer;                                                                                           \
297         int args[] = {__VA_ARGS__};                                                                                    \
298         int argc = sizeof(args) / sizeof(int);                                                                         \
299         if (argc == 0) {                                                                                               \
300             buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, width, height, format);                        \
301         } else if (argc == 2) {                                                                                        \
302             buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, args[0], args[1], format);                     \
303         } else {                                                                                                       \
304             printf("invalid parameter\n");                                                                             \
305         }                                                                                                              \
306         buffer;                                                                                                        \
307     })
308 
309 #define wrapbuffer_fd(fd, width, height, format, ...)                                                                  \
310     ( {                                                                                                                \
311         rga_buffer_t buffer;                                                                                           \
312         int args[] = {__VA_ARGS__};                                                                                    \
313         int argc = sizeof(args) / sizeof(int);                                                                         \
314         if (argc == 0) {                                                                                               \
315             buffer = wrapbuffer_fd_t(fd, width, height, width, height, format);                                        \
316         } else if (argc == 2) {                                                                                        \
317             buffer = wrapbuffer_fd_t(fd, width, height, args[0], args[1], format);                                     \
318         } else {                                                                                                       \
319             printf("invalid parameter\n");                                                                             \
320         }                                                                                                              \
321         buffer;                                                                                                        \
322     })
323 
324 IM_API rga_buffer_t wrapbuffer_virtualaddr_t(void *vir_addr, int width, int height, int wstride, int hstride,
325                                              int format);
326 IM_API rga_buffer_t wrapbuffer_physicaladdr_t(void *phy_addr, int width, int height, int wstride, int hstride,
327                                               int format);
328 IM_API rga_buffer_t wrapbuffer_fd_t(int fd, int width, int height, int wstride, int hstride, int format);
329 
330 /*
331  * Get RGA basic information, supported resolution, supported format, etc.
332  *
333  * @param name
334  *      RGA_VENDOR
335  *      RGA_VERSION
336  *      RGA_MAX_INPUT
337  *      RGA_MAX_OUTPUT
338  *      RGA_INPUT_FORMAT
339  *      RGA_OUTPUT_FORMAT
340  *      RGA_EXPECTED
341  *      RGA_ALL
342  *
343  * @returns a usage describing properties of RGA.
344  */
345 IM_API IM_STATUS rga_get_info(rga_info_table_entry *return_table);
346 
347 /*
348  * Query RGA basic information, supported resolution, supported format, etc.
349  *
350  * @param name
351  *      RGA_VENDOR
352  *      RGA_VERSION
353  *      RGA_MAX_INPUT
354  *      RGA_MAX_OUTPUT
355  *      RGA_INPUT_FORMAT
356  *      RGA_OUTPUT_FORMAT
357  *      RGA_EXPECTED
358  *      RGA_ALL
359  *
360  * @returns a string describing properties of RGA.
361  */
362 IM_API const char *querystring(int name);
363 
364 /*
365  * check RGA basic information, supported resolution, supported format, etc.
366  *
367  * @param src
368  * @param dst
369  * @param src_rect
370  * @param dst_rect
371  * @param mode_usage
372  *
373  * @returns no error or else negative error code.
374  */
375 #define imcheck(src, dst, src_rect, dst_rect, ...)                                                                     \
376     ( {                                                                                                                \
377         IM_STATUS ret = IM_STATUS_NOERROR;                                                                             \
378         rga_buffer_t pat;                                                                                              \
379         im_rect pat_rect;                                                                                              \
380         errno_t eok = memset_s(&pat, sizeof(rga_buffer_t), 0, sizeof(rga_buffer_t));                                   \
381         if (!eok) {                                                                                                    \
382             printf("memset_s failed!\n");                                                                              \
383         }                                                                                                              \
384         eok = memset_s(&pat_rect, sizeof(im_rect), 0, sizeof(im_rect));                                                \
385         if (!eok) {                                                                                                    \
386             printf("memset_s failed!\n");                                                                              \
387         }                                                                                                              \
388         int args[] = {__VA_ARGS__};                                                                                    \
389         int argc = sizeof(args) / sizeof(int);                                                                         \
390         if (argc == 0) {                                                                                               \
391             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0);                                           \
392         } else if (argc == 1) {                                                                                        \
393             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, args[0]);                                     \
394         } else {                                                                                                       \
395             ret = IM_STATUS_FAILED;                                                                                    \
396             printf("check failed\n");                                                                                  \
397         }                                                                                                              \
398         ret;                                                                                                           \
399     })
400 #define imcheck_composite(src, dst, pat, src_rect, dst_rect, pat_rect, ...)                                            \
401     ( {                                                                                                                \
402         IM_STATUS ret = IM_STATUS_NOERROR;                                                                             \
403         int args[] = {__VA_ARGS__};                                                                                    \
404         int argc = sizeof(args) / sizeof(int);                                                                         \
405         if (argc == 0) {                                                                                               \
406             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0);                                           \
407         } else if (argc == 1) {                                                                                        \
408             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, args[0]);                                     \
409         } else {                                                                                                       \
410             ret = IM_STATUS_FAILED;                                                                                    \
411             printf("check failed\n");                                                                                  \
412         }                                                                                                              \
413         ret;                                                                                                           \
414     })
415 IM_API IM_STATUS imcheck_t(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat,
416                            const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect,
417                            const int mdoe_usage);
418 
419 /*
420  * Resize
421  *
422  * @param src
423  * @param dst
424  * @param fx
425  * @param fy
426  * @param interpolation
427  * @param sync
428  *      wait until operation complete
429  *
430  * @returns success or else negative error code.
431  */
432 #define imresize(src, dst, ...)                                                                                        \
433     ( {                                                                                                                \
434         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
435         double args[] = {__VA_ARGS__};                                                                                 \
436         int argc = sizeof(args) / sizeof(double);                                                                      \
437         if (argc == 0) {                                                                                               \
438             ret = imresize_t(src, dst, 0, 0, INTER_LINEAR, 1);                                                         \
439         } else if (argc == 2) {                                                                                        \
440             ret = imresize_t(src, dst, args[0], args[1], INTER_LINEAR, 1);                                             \
441         } else if (argc == 3) {                                                                                        \
442             ret = imresize_t(src, dst, args[0], args[1], (int)args[2], 1);                                             \
443         } else if (argc == 4) {                                                                                        \
444             ret = imresize_t(src, dst, args[0], args[1], (int)args[2], (int)args[3]);                                  \
445         } else {                                                                                                       \
446             ret = IM_STATUS_INVALID_PARAM;                                                                             \
447             printf("invalid parameter\n");                                                                             \
448         }                                                                                                              \
449         ret;                                                                                                           \
450     })
451 
452 #define impyramid(src, dst, direction)                                                                                 \
453     imresize_t(src, dst, (direction) == IM_UP_SCALE ? 0.5 : 2, (direction) == IM_UP_SCALE ? 0.5 : 2, INTER_LINEAR, 1)
454 
455 IM_API IM_STATUS imresize_t(const rga_buffer_t src, rga_buffer_t dst, double fx, double fy, int interpolation,
456                             int sync);
457 
458 /*
459  * Crop
460  *
461  * @param src
462  * @param dst
463  * @param rect
464  * @param sync
465  *      wait until operation complete
466  *
467  * @returns success or else negative error code.
468  */
469 #define imcrop(src, dst, rect, ...)                                                                                    \
470     ( {                                                                                                                \
471         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
472         int args[] = {__VA_ARGS__};                                                                                    \
473         int argc = sizeof(args) / sizeof(int);                                                                         \
474         if (argc == 0) {                                                                                               \
475             ret = imcrop_t(src, dst, rect, 1);                                                                         \
476         } else if (argc == 1) {                                                                                        \
477             ret = imcrop_t(src, dst, rect, args[0]);                                                                   \
478             ;                                                                                                          \
479         } else {                                                                                                       \
480             ret = IM_STATUS_INVALID_PARAM;                                                                             \
481             printf("invalid parameter\n");                                                                             \
482         }                                                                                                              \
483         ret;                                                                                                           \
484     })
485 
486 IM_API IM_STATUS imcrop_t(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync);
487 
488 /*
489  * rotation
490  *
491  * @param src
492  * @param dst
493  * @param rotation
494  *      IM_HAL_TRANSFORM_ROT_90
495  *      IM_HAL_TRANSFORM_ROT_180
496  *      IM_HAL_TRANSFORM_ROT_270
497  * @param sync
498  *      wait until operation complete
499  *
500  * @returns success or else negative error code.
501  */
502 #define imrotate(src, dst, rotation, ...)                                                                              \
503     ( {                                                                                                                \
504         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
505         int args[] = {__VA_ARGS__};                                                                                    \
506         int argc = sizeof(args) / sizeof(int);                                                                         \
507         if (argc == 0) {                                                                                               \
508             ret = imrotate_t(src, dst, rotation, 1);                                                                   \
509         } else if (argc == 1) {                                                                                        \
510             ret = imrotate_t(src, dst, rotation, args[0]);                                                             \
511             ;                                                                                                          \
512         } else {                                                                                                       \
513             ret = IM_STATUS_INVALID_PARAM;                                                                             \
514             printf("invalid parameter\n");                                                                             \
515         }                                                                                                              \
516         ret;                                                                                                           \
517     })
518 
519 IM_API IM_STATUS imrotate_t(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync);
520 
521 /*
522  * flip
523  *
524  * @param src
525  * @param dst
526  * @param mode
527  *      IM_HAL_TRANSFORM_FLIP_H
528  *      IM_HAL_TRANSFORM_FLIP_V
529  * @param sync
530  *      wait until operation complete
531  *
532  * @returns success or else negative error code.
533  */
534 #define imflip(src, dst, mode, ...)                                                                                    \
535     ( {                                                                                                                \
536         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
537         int args[] = {__VA_ARGS__};                                                                                    \
538         int argc = sizeof(args) / sizeof(int);                                                                         \
539         if (argc == 0) {                                                                                               \
540             ret = imflip_t(src, dst, mode, 1);                                                                         \
541         } else if (argc == 1) {                                                                                        \
542             ret = imflip_t(src, dst, mode, args[0]);                                                                   \
543             ;                                                                                                          \
544         } else {                                                                                                       \
545             ret = IM_STATUS_INVALID_PARAM;                                                                             \
546             printf("invalid parameter\n");                                                                             \
547         }                                                                                                              \
548         ret;                                                                                                           \
549     })
550 
551 IM_API IM_STATUS imflip_t(const rga_buffer_t src, rga_buffer_t dst, int mode, int sync);
552 
553 /*
554  * fill/reset/draw
555  *
556  * @param src
557  * @param dst
558  * @param rect
559  * @param color
560  * @param sync
561  *      wait until operation complete
562  *
563  * @returns success or else negative error code.
564  */
565 #define imfill(buf, rect, color, ...)                                                                                  \
566     ( {                                                                                                                \
567         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
568         int args[] = {__VA_ARGS__};                                                                                    \
569         int argc = sizeof(args) / sizeof(int);                                                                         \
570         if (argc == 0) {                                                                                               \
571             ret = imfill_t(buf, rect, color, 1);                                                                       \
572         } else if (argc == 1) {                                                                                        \
573             ret = imfill_t(buf, rect, color, args[0]);                                                                 \
574             ;                                                                                                          \
575         } else {                                                                                                       \
576             ret = IM_STATUS_INVALID_PARAM;                                                                             \
577             printf("invalid parameter\n");                                                                             \
578         }                                                                                                              \
579         ret;                                                                                                           \
580     })
581 
582 #define imreset(buf, rect, color, ...)                                                                                 \
583     ( {                                                                                                                \
584         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
585         int args[] = {__VA_ARGS__};                                                                                    \
586         int argc = sizeof(args) / sizeof(int);                                                                         \
587         if (argc == 0) {                                                                                               \
588             ret = imfill_t(buf, rect, color, 1);                                                                       \
589         } else if (argc == 1) {                                                                                        \
590             ret = imfill_t(buf, rect, color, args[0]);                                                                 \
591             ;                                                                                                          \
592         } else {                                                                                                       \
593             ret = IM_STATUS_INVALID_PARAM;                                                                             \
594             printf("invalid parameter\n");                                                                             \
595         }                                                                                                              \
596         ret;                                                                                                           \
597     })
598 
599 #define imdraw(buf, rect, color, ...)                                                                                  \
600     ( {                                                                                                                \
601         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
602         int args[] = {__VA_ARGS__};                                                                                    \
603         int argc = sizeof(args) / sizeof(int);                                                                         \
604         if (argc == 0) {                                                                                               \
605             ret = imfill_t(buf, rect, color, 1);                                                                       \
606         } else if (argc == 1) {                                                                                        \
607             ret = imfill_t(buf, rect, color, args[0]);                                                                 \
608             ;                                                                                                          \
609         } else {                                                                                                       \
610             ret = IM_STATUS_INVALID_PARAM;                                                                             \
611             printf("invalid parameter\n");                                                                             \
612         }                                                                                                              \
613         ret;                                                                                                           \
614     })
615 IM_API IM_STATUS imfill_t(rga_buffer_t dst, im_rect rect, int color, int sync);
616 
617 /*
618  * palette
619  *
620  * @param src
621  * @param dst
622  * @param lut
623  * @param sync
624  *      wait until operation complete
625  *
626  * @returns success or else negative error code.
627  */
628 #define impalette(src, dst, lut, ...)                                                                                  \
629     ( {                                                                                                                \
630         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
631         int args[] = {__VA_ARGS__};                                                                                    \
632         int argc = sizeof(args) / sizeof(int);                                                                         \
633         if (argc == 0) {                                                                                               \
634             ret = impalette_t(src, dst, lut, 1);                                                                       \
635         } else if (argc == 1) {                                                                                        \
636             ret = impalette_t(src, dst, lut, args[0]);                                                                 \
637             ;                                                                                                          \
638         } else {                                                                                                       \
639             ret = IM_STATUS_INVALID_PARAM;                                                                             \
640             printf("invalid parameter\n");                                                                             \
641         }                                                                                                              \
642         ret;                                                                                                           \
643     })
644 IM_API IM_STATUS impalette_t(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync);
645 
646 /*
647  * translate
648  *
649  * @param src
650  * @param dst
651  * @param x
652  * @param y
653  * @param sync
654  *      wait until operation complete
655  *
656  * @returns success or else negative error code.
657  */
658 #define imtranslate(src, dst, x, y, ...)                                                                               \
659     ( {                                                                                                                \
660         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
661         int args[] = {__VA_ARGS__};                                                                                    \
662         int argc = sizeof(args) / sizeof(int);                                                                         \
663         if (argc == 0) {                                                                                               \
664             ret = imtranslate_t(src, dst, x, y, 1);                                                                    \
665         } else if (argc == 1) {                                                                                        \
666             ret = imtranslate_t(src, dst, x, y, args[0]);                                                              \
667             ;                                                                                                          \
668         } else {                                                                                                       \
669             ret = IM_STATUS_INVALID_PARAM;                                                                             \
670             printf("invalid parameter\n");                                                                             \
671         }                                                                                                              \
672         ret;                                                                                                           \
673     })
674 IM_API IM_STATUS imtranslate_t(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync);
675 
676 /*
677  * copy
678  *
679  * @param src
680  * @param dst
681  * @param sync
682  *      wait until operation complete
683  *
684  * @returns success or else negative error code.
685  */
686 #define imcopy(src, dst, ...)                                                                                          \
687     ( {                                                                                                                \
688         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
689         int args[] = {__VA_ARGS__};                                                                                    \
690         int argc = sizeof(args) / sizeof(int);                                                                         \
691         if (argc == 0) {                                                                                               \
692             ret = imcopy_t(src, dst, 1);                                                                               \
693         } else if (argc == 1) {                                                                                        \
694             ret = imcopy_t(src, dst, args[0]);                                                                         \
695             ;                                                                                                          \
696         } else {                                                                                                       \
697             ret = IM_STATUS_INVALID_PARAM;                                                                             \
698             printf("invalid parameter\n");                                                                             \
699         }                                                                                                              \
700         ret;                                                                                                           \
701     })
702 
703 IM_API IM_STATUS imcopy_t(const rga_buffer_t src, rga_buffer_t dst, int sync);
704 
705 /*
706  * blend (SRC + DST -> DST or SRCA + SRCB -> DST)
707  *
708  * @param srcA
709  * @param srcB can be NULL.
710  * @param dst
711  * @param mode
712  *      IM_ALPHA_BLEND_MODE
713  * @param sync
714  *      wait until operation complete
715  *
716  * @returns success or else negative error code.
717  */
718 #define imblend(srcA, dst, ...)                                                                                        \
719     ( {                                                                                                                \
720         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
721         rga_buffer_t srcB;                                                                                             \
722         errno_t eok = memset_s(&srcB, sizeof(rga_buffer_t), 0x00, sizeof(rga_buffer_t));                               \
723         if (!eok) {                                                                                                    \
724             printf("memset_s failed!\n");                                                                              \
725         }                                                                                                              \
726         int args[] = {__VA_ARGS__};                                                                                    \
727         int argc = sizeof(args) / sizeof(int);                                                                         \
728         if (argc == 0) {                                                                                               \
729             ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1);                                              \
730         } else if (argc == 1) {                                                                                        \
731             ret = imblend_t(srcA, srcB, dst, args[0], 1);                                                              \
732         } else if (argc == 2) {                                                                                        \
733             ret = imblend_t(srcA, srcB, dst, args[0], args[1]);                                                        \
734         } else {                                                                                                       \
735             ret = IM_STATUS_INVALID_PARAM;                                                                             \
736             printf("invalid parameter\n");                                                                             \
737         }                                                                                                              \
738         ret;                                                                                                           \
739     })
740 #define imcomposite(srcA, srcB, dst, ...)                                                                              \
741     ( {                                                                                                                \
742         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
743         int args[] = {__VA_ARGS__};                                                                                    \
744         int argc = sizeof(args) / sizeof(int);                                                                         \
745         if (argc == 0) {                                                                                               \
746             ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1);                                              \
747         } else if (argc == 1) {                                                                                        \
748             ret = imblend_t(srcA, srcB, dst, args[0], 1);                                                              \
749         } else if (argc == 2) {                                                                                        \
750             ret = imblend_t(srcA, srcB, dst, args[0], args[1]);                                                        \
751         } else {                                                                                                       \
752             ret = IM_STATUS_INVALID_PARAM;                                                                             \
753             printf("invalid parameter\n");                                                                             \
754         }                                                                                                              \
755         ret;                                                                                                           \
756     })
757 IM_API IM_STATUS imblend_t(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode, int sync);
758 
759 /*
760  * color key
761  *
762  * @param src
763  * @param dst
764  * @param colorkey_range
765  *      max color
766  *      min color
767  * @param sync
768  *      wait until operation complete
769  *
770  * @returns success or else negative error code.
771  */
772 #define imcolorkey(src, dst, range, ...)                                                                               \
773     ( {                                                                                                                \
774         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
775         int args[] = {__VA_ARGS__};                                                                                    \
776         int argc = sizeof(args) / sizeof(int);                                                                         \
777         if (argc == 0) {                                                                                               \
778             ret = imcolorkey_t(src, dst, range, IM_ALPHA_COLORKEY_NORMAL, 1);                                          \
779         } else if (argc == 1) {                                                                                        \
780             ret = imcolorkey_t(src, dst, range, args[0], 1);                                                           \
781         } else if (argc == 2) {                                                                                        \
782             ret = imcolorkey_t(src, dst, range, args[0], args[1]);                                                     \
783         } else {                                                                                                       \
784             ret = IM_STATUS_INVALID_PARAM;                                                                             \
785             printf("invalid parameter\n");                                                                             \
786         }                                                                                                              \
787         ret;                                                                                                           \
788     })
789 IM_API IM_STATUS imcolorkey_t(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode, int sync);
790 
791 /*
792  * format convert
793  *
794  * @param src
795  * @param dst
796  * @param sfmt
797  * @param dfmt
798  * @param mode
799  *      color space mode: IM_COLOR_SPACE_MODE
800  * @param sync
801  *      wait until operation complete
802  *
803  * @returns success or else negative error code.
804  */
805 #define imcvtcolor(src, dst, sfmt, dfmt, ...)                                                                          \
806     ( {                                                                                                                \
807         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
808         int args[] = {__VA_ARGS__};                                                                                    \
809         int argc = sizeof(args) / sizeof(int);                                                                         \
810         if (argc == 0) {                                                                                               \
811             ret = imcvtcolor_t(src, dst, sfmt, dfmt, IM_COLOR_SPACE_DEFAULT, 1);                                       \
812         } else if (argc == 1) {                                                                                        \
813             ret = imcvtcolor_t(src, dst, sfmt, dfmt, args[0], 1);                                                      \
814         } else if (argc == 2) {                                                                                        \
815             ret = imcvtcolor_t(src, dst, sfmt, dfmt, args[0], args[1]);                                                \
816         } else {                                                                                                       \
817             ret = IM_STATUS_INVALID_PARAM;                                                                             \
818             printf("invalid parameter\n");                                                                             \
819         }                                                                                                              \
820         ret;                                                                                                           \
821     })
822 
823 IM_API IM_STATUS imcvtcolor_t(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode, int sync);
824 
825 /*
826  * nn quantize
827  *
828  * @param src
829  * @param dst
830  * @param nninfo
831  * @param sync
832  *      wait until operation complete
833  *
834  * @returns success or else negative error code.
835  */
836 #define imquantize(src, dst, nn_info, ...)                                                                             \
837     ( {                                                                                                                \
838         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
839         int args[] = {__VA_ARGS__};                                                                                    \
840         int argc = sizeof(args) / sizeof(int);                                                                         \
841         if (argc == 0) {                                                                                               \
842             ret = imquantize_t(src, dst, nn_info, 1);                                                                  \
843         } else if (argc == 1) {                                                                                        \
844             ret = imquantize_t(src, dst, nn_info, args[0]);                                                            \
845             ;                                                                                                          \
846         } else {                                                                                                       \
847             ret = IM_STATUS_INVALID_PARAM;                                                                             \
848             printf("invalid parameter\n");                                                                             \
849         }                                                                                                              \
850         ret;                                                                                                           \
851     })
852 
853 IM_API IM_STATUS imquantize_t(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync);
854 
855 /*
856  * ROP
857  *
858  * @param src
859  * @param dst
860  * @param rop_code
861  * @param sync
862  *      wait until operation complete
863  *
864  * @returns success or else negative error code.
865  */
866 #define imrop(src, dst, rop_code, ...)                                                                                 \
867     ( {                                                                                                                \
868         IM_STATUS ret = IM_STATUS_SUCCESS;                                                                             \
869         int args[] = {__VA_ARGS__};                                                                                    \
870         int argc = sizeof(args) / sizeof(int);                                                                         \
871         if (argc == 0) {                                                                                               \
872             ret = imrop_t(src, dst, rop_code, 1);                                                                      \
873         } else if (argc == 1) {                                                                                        \
874             ret = imrop_t(src, dst, rop_code, args[0]);                                                                \
875             ;                                                                                                          \
876         } else {                                                                                                       \
877             ret = IM_STATUS_INVALID_PARAM;                                                                             \
878             printf("invalid parameter\n");                                                                             \
879         }                                                                                                              \
880         ret;                                                                                                           \
881     })
882 IM_API IM_STATUS imrop_t(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync);
883 
884 /*
885  * process
886  *
887  * @param src
888  * @param dst
889  * @param usage
890  * @param ...
891  *      wait until operation complete
892  *
893  * @returns success or else negative error code.
894  */
895 IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, im_rect srect, im_rect drect,
896                            im_rect prect, int usage);
897 
898 /*
899  * block until all execution is complete
900  *
901  * @returns success or else negative error code.
902  */
903 IM_API IM_STATUS imsync(void);
904 
905 #ifdef __cplusplus
906 }
907 #endif
908 #endif /* _im2d_h_ */
909