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 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 #include "im2d_version.h"
28 #include "im2d_type.h"
29 
30 #ifndef IM_API
31 #define IM_API /* define API export as needed */
32 #endif
33 
34 #define RGA_GET_MIN(n1, n2) ((n1) < (n2) ? (n1) : (n2))
35 
36 /*
37  * @return error message string
38  */
39 #define imStrError(...) \
40     ({ \
41         const char* im2d_api_err; \
42         int __args[] = {__VA_ARGS__}; \
43         int __argc = sizeof(__args)/sizeof(int); \
44         if (__argc == 0) { \
45             im2d_api_err = imStrError_t(IM_STATUS_INVALID_PARAM); \
46         } else if (__argc == 1){ \
47             im2d_api_err = imStrError_t((IM_STATUS)__args[0]); \
48         } else { \
49             im2d_api_err = ("Fatal error, imStrError() too many parameters\n"); \
50             printf("Fatal error, imStrError() too many parameters\n"); \
51         } \
52         im2d_api_err; \
53     })
54 IM_API const char* imStrError_t(IM_STATUS status);
55 
56 /*
57  * Import external buffers into RGA driver.
58  *
59  * @param fd/va/pa
60  *      Select dma_fd/virtual_address/physical_address by buffer type
61  * @param param
62  *      Configure buffer parameters
63  *
64  * @return rga_buffer_handle_t
65  */
66 IM_API rga_buffer_handle_t importbuffer_fd(int fd, im_handle_param_t *param);
67 IM_API rga_buffer_handle_t importbuffer_virtualaddr(void *va, im_handle_param_t *param);
68 IM_API rga_buffer_handle_t importbuffer_physicaladdr(uint64_t pa, im_handle_param_t *param);
69 
70 /*
71  * Import external buffers into RGA driver.
72  *
73  * @param handle
74  *      rga buffer handle
75  *
76  * @return success or else negative error code.
77  */
78 IM_API IM_STATUS releasebuffer_handle(rga_buffer_handle_t handle);
79 
80 /*
81  * Wrap image Parameters.
82  *
83  * @param handle
84  *      RGA buffer handle.
85  * @param width
86  *      Width of image manipulation area.
87  * @param height
88  *      Height of image manipulation area.
89  * @param wstride
90  *      Width pixel stride, default (width = wstride).
91  * @param hstride
92  *      Height pixel stride, default (height = hstride).
93  * @param format
94  *      Image format.
95  *
96  * @return rga_buffer_t
97  */
98 #define wrapbuffer_handle(handle, width, height, format, ...) \
99     ({ \
100         rga_buffer_t im2d_api_buffer; \
101         int __args[] = {__VA_ARGS__}; \
102         int __argc = sizeof(__args)/sizeof(int); \
103         if (__argc == 0) { \
104             im2d_api_buffer = wrapbuffer_handle_t(handle, width, height, width, height, format); \
105         } else if (__argc == 2){ \
106             im2d_api_buffer = wrapbuffer_handle_t(handle, width, height, __args[0], __args[1], format); \
107         } else { \
108             printf("invalid parameter\n"); \
109         } \
110         im2d_api_buffer; \
111     })
112 IM_API rga_buffer_t wrapbuffer_handle_t(rga_buffer_handle_t handle, int width, int height, int wstride, int hstride, int format);
113 
114 /* For legarcy. */
115 #define wrapbuffer_virtualaddr(vir_addr, width, height, format, ...) \
116     ({ \
117         rga_buffer_t im2d_api_buffer; \
118         int __args[] = {__VA_ARGS__}; \
119         int __argc = sizeof(__args)/sizeof(int); \
120         if (__argc == 0) { \
121             im2d_api_buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, width, height, format); \
122         } else if (__argc == 2){ \
123             im2d_api_buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, __args[0], __args[1], format); \
124         } else { \
125             printf("invalid parameter\n"); \
126         } \
127         im2d_api_buffer; \
128     })
129 
130 #define wrapbuffer_physicaladdr(phy_addr, width, height, format, ...) \
131     ({ \
132         rga_buffer_t im2d_api_buffer; \
133         int __args[] = {__VA_ARGS__}; \
134         int __argc = sizeof(__args)/sizeof(int); \
135         if (__argc == 0) { \
136             im2d_api_buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, width, height, format); \
137         } else if (__argc == 2){ \
138             im2d_api_buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, __args[0], __args[1], format); \
139         } else { \
140             printf("invalid parameter\n"); \
141         } \
142         im2d_api_buffer; \
143     })
144 
145 #define wrapbuffer_fd(fd, width, height, format, ...) \
146     ({ \
147         rga_buffer_t im2d_api_buffer; \
148         int __args[] = {__VA_ARGS__}; \
149         int __argc = sizeof(__args)/sizeof(int); \
150         if (__argc == 0) { \
151             im2d_api_buffer = wrapbuffer_fd_t(fd, width, height, width, height, format); \
152         } else if (__argc == 2){ \
153             im2d_api_buffer = wrapbuffer_fd_t(fd, width, height, __args[0], __args[1], format); \
154         } else { \
155             printf("invalid parameter\n"); \
156         } \
157         im2d_api_buffer; \
158     })
159 IM_API rga_buffer_t wrapbuffer_virtualaddr_t(void* vir_addr, int width, int height, int wstride, int hstride, int format);
160 IM_API rga_buffer_t wrapbuffer_physicaladdr_t(void* phy_addr, int width, int height, int wstride, int hstride, int format);
161 IM_API rga_buffer_t wrapbuffer_fd_t(int fd, int width, int height, int wstride, int hstride, int format);
162 
163 /*
164  * Query RGA basic information, supported resolution, supported format, etc.
165  *
166  * @param name
167  *      RGA_VENDOR
168  *      RGA_VERSION
169  *      RGA_MAX_INPUT
170  *      RGA_MAX_OUTPUT
171  *      RGA_INPUT_FORMAT
172  *      RGA_OUTPUT_FORMAT
173  *      RGA_EXPECTED
174  *      RGA_ALL
175  *
176  * @returns a string describing properties of RGA.
177  */
178 IM_API const char* querystring(int name);
179 
180 /*
181  * check RGA basic information, supported resolution, supported format, etc.
182  *
183  * @param src
184  * @param dst
185  * @param src_rect
186  * @param dst_rect
187  * @param mode_usage
188  *
189  * @returns no error or else negative error code.
190  */
191 #define imcheck(src, dst, src_rect, dst_rect, ...) \
192     ({ \
193         IM_STATUS __ret = IM_STATUS_NOERROR; \
194         rga_buffer_t __pat; \
195         im_rect __pat_rect; \
196         memset(&__pat, 0, sizeof(rga_buffer_t)); \
197         memset(&__pat_rect, 0, sizeof(im_rect)); \
198         int __args[] = {__VA_ARGS__}; \
199         int __argc = sizeof(__args)/sizeof(int); \
200         if (__argc == 0) { \
201             rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&__pat), \
202                               (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&__pat_rect), 0); \
203             __ret = imcheck_t(src, dst, __pat, src_rect, dst_rect, __pat_rect, 0); \
204         } else if (__argc == 1){ \
205             rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&__pat), \
206                               (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&__pat_rect), __args[0]); \
207             __ret = imcheck_t(src, dst, __pat, src_rect, dst_rect, __pat_rect, __args[0]); \
208         } else { \
209             __ret = IM_STATUS_FAILED; \
210             printf("check failed\n"); \
211         } \
212         __ret; \
213     })
214 #define imcheck_composite(src, dst, pat, src_rect, dst_rect, pat_rect, ...) \
215     ({ \
216         IM_STATUS __ret = IM_STATUS_NOERROR; \
217         int __args[] = {__VA_ARGS__}; \
218         int __argc = sizeof(__args)/sizeof(int); \
219         if (__argc == 0) { \
220             rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&pat), \
221                               (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&pat_rect), 0); \
222             __ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \
223         } else if (__argc == 1){ \
224             rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&pat), \
225                               (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&pat_rect), __args[0]); \
226             __ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, __args[0]); \
227         } else { \
228             __ret = IM_STATUS_FAILED; \
229             printf("check failed\n"); \
230         } \
231         __ret; \
232     })
233 IM_API void rga_check_perpare(rga_buffer_t *src, rga_buffer_t *dst, rga_buffer_t *pat,
234                               im_rect *src_rect, im_rect *dst_rect, im_rect *pat_rect, int mode_usage);
235 IM_API IM_STATUS imcheck_t(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat,
236                            const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect, const int mode_usage);
237 
238 /*
239  * Resize
240  *
241  * @param src
242  * @param dst
243  * @param fx
244  * @param fy
245  * @param interpolation
246  * @param sync
247  *      wait until operation complete
248  *
249  * @returns success or else negative error code.
250  */
251 #define imresize(src, dst, ...) \
252     ({ \
253         IM_STATUS __ret = IM_STATUS_SUCCESS; \
254         double __args[] = {__VA_ARGS__}; \
255         int __argc = sizeof(__args)/sizeof(double); \
256         if (__argc == 0) { \
257             __ret = imresize_t(src, dst, 0, 0, INTER_LINEAR, 1); \
258         } else if (__argc == 2){ \
259             __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], INTER_LINEAR, 1); \
260         } else if (__argc == 3){ \
261             __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], (int)__args[RGA_GET_MIN(__argc, 2)], 1); \
262         } else if (__argc == 4){ \
263             __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], (int)__args[RGA_GET_MIN(__argc, 2)], (int)__args[RGA_GET_MIN(__argc, 3)]); \
264         } else { \
265             __ret = IM_STATUS_INVALID_PARAM; \
266             printf("invalid parameter\n"); \
267         } \
268         __ret; \
269     })
270 
271 #define impyramid(src, dst, direction) \
272         imresize_t(src, \
273                    dst, \
274                    direction == IM_UP_SCALE ? 0.5 : 2, \
275                    direction == IM_UP_SCALE ? 0.5 : 2, \
276                    INTER_LINEAR, 1)
277 
278 IM_API IM_STATUS imresize_t(const rga_buffer_t src, rga_buffer_t dst, double fx, double fy, int interpolation, int sync);
279 
280 /*
281  * Crop
282  *
283  * @param src
284  * @param dst
285  * @param rect
286  * @param sync
287  *      wait until operation complete
288  *
289  * @returns success or else negative error code.
290  */
291 #define imcrop(src, dst, rect, ...) \
292     ({ \
293         IM_STATUS __ret = IM_STATUS_SUCCESS; \
294         int __args[] = {__VA_ARGS__}; \
295         int __argc = sizeof(__args)/sizeof(int); \
296         if (__argc == 0) { \
297             __ret = imcrop_t(src, dst, rect, 1); \
298         } else if (__argc == 1){ \
299             __ret = imcrop_t(src, dst, rect, (int)__args[RGA_GET_MIN(__argc, 0)]); \
300         } else { \
301             __ret = IM_STATUS_INVALID_PARAM; \
302             printf("invalid parameter\n"); \
303         } \
304         __ret; \
305     })
306 
307 IM_API IM_STATUS imcrop_t(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync);
308 
309 /*
310  * rotation
311  *
312  * @param src
313  * @param dst
314  * @param rotation
315  *      IM_HAL_TRANSFORM_ROT_90
316  *      IM_HAL_TRANSFORM_ROT_180
317  *      IM_HAL_TRANSFORM_ROT_270
318  * @param sync
319  *      wait until operation complete
320  *
321  * @returns success or else negative error code.
322  */
323 #define imrotate(src, dst, rotation, ...) \
324     ({ \
325         IM_STATUS __ret = IM_STATUS_SUCCESS; \
326         int __args[] = {__VA_ARGS__}; \
327         int __argc = sizeof(__args)/sizeof(int); \
328         if (__argc == 0) { \
329             __ret = imrotate_t(src, dst, rotation, 1); \
330         } else if (__argc == 1){ \
331             __ret = imrotate_t(src, dst, rotation, (int)__args[RGA_GET_MIN(__argc, 0)]); \
332         } else { \
333             __ret = IM_STATUS_INVALID_PARAM; \
334             printf("invalid parameter\n"); \
335         } \
336         __ret; \
337     })
338 
339 IM_API IM_STATUS imrotate_t(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync);
340 
341 /*
342  * flip
343  *
344  * @param src
345  * @param dst
346  * @param mode
347  *      IM_HAL_TRANSFORM_FLIP_H
348  *      IM_HAL_TRANSFORM_FLIP_V
349  * @param sync
350  *      wait until operation complete
351  *
352  * @returns success or else negative error code.
353  */
354 #define imflip(src, dst, mode, ...) \
355     ({ \
356         IM_STATUS __ret = IM_STATUS_SUCCESS; \
357         int __args[] = {__VA_ARGS__}; \
358         int __argc = sizeof(__args)/sizeof(int); \
359         if (__argc == 0) { \
360             __ret = imflip_t(src, dst, mode, 1); \
361         } else if (__argc == 1){ \
362             __ret = imflip_t(src, dst, mode, (int)__args[RGA_GET_MIN(__argc, 0)]); \
363         } else { \
364             __ret = IM_STATUS_INVALID_PARAM; \
365             printf("invalid parameter\n"); \
366         } \
367         __ret; \
368     })
369 
370 IM_API IM_STATUS imflip_t (const rga_buffer_t src, rga_buffer_t dst, int mode, int sync);
371 
372 /*
373  * fill/reset/draw
374  *
375  * @param src
376  * @param dst
377  * @param rect
378  * @param color
379  * @param sync
380  *      wait until operation complete
381  *
382  * @returns success or else negative error code.
383  */
384 #define imfill(buf, rect, color, ...) \
385     ({ \
386         IM_STATUS __ret = IM_STATUS_SUCCESS; \
387         int __args[] = {__VA_ARGS__}; \
388         int __argc = sizeof(__args)/sizeof(int); \
389         if (__argc == 0) { \
390             __ret = imfill_t(buf, rect, color, 1); \
391         } else if (__argc == 1){ \
392             __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \
393         } else { \
394             __ret = IM_STATUS_INVALID_PARAM; \
395             printf("invalid parameter\n"); \
396         } \
397         __ret; \
398     })
399 
400 #define imreset(buf, rect, color, ...) \
401     ({ \
402         IM_STATUS __ret = IM_STATUS_SUCCESS; \
403         int __args[] = {__VA_ARGS__}; \
404         int __argc = sizeof(__args)/sizeof(int); \
405         if (__argc == 0) { \
406             __ret = imfill_t(buf, rect, color, 1); \
407         } else if (__argc == 1){ \
408             __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \
409         } else { \
410             __ret = IM_STATUS_INVALID_PARAM; \
411             printf("invalid parameter\n"); \
412         } \
413         __ret; \
414     })
415 
416 #define imdraw(buf, rect, color, ...) \
417     ({ \
418         IM_STATUS __ret = IM_STATUS_SUCCESS; \
419         int __args[] = {__VA_ARGS__}; \
420         int __argc = sizeof(__args)/sizeof(int); \
421         if (__argc == 0) { \
422             __ret = imfill_t(buf, rect, color, 1); \
423         } else if (__argc == 1){ \
424             __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \
425         } else { \
426             __ret = IM_STATUS_INVALID_PARAM; \
427             printf("invalid parameter\n"); \
428         } \
429         __ret; \
430     })
431 IM_API IM_STATUS imfill_t(rga_buffer_t dst, im_rect rect, int color, int sync);
432 
433 /*
434  * palette
435  *
436  * @param src
437  * @param dst
438  * @param lut
439  * @param sync
440  *      wait until operation complete
441  *
442  * @returns success or else negative error code.
443  */
444 #define impalette(src, dst, lut,  ...) \
445     ({ \
446         IM_STATUS __ret = IM_STATUS_SUCCESS; \
447         int __args[] = {__VA_ARGS__}; \
448         int __argc = sizeof(__args)/sizeof(int); \
449         if (__argc == 0) { \
450             __ret = impalette_t(src, dst, lut, 1); \
451         } else if (__argc == 1){ \
452             __ret = impalette_t(src, dst, lut, (int)__args[RGA_GET_MIN(__argc, 0)]); \
453         } else { \
454             __ret = IM_STATUS_INVALID_PARAM; \
455             printf("invalid parameter\n"); \
456         } \
457         __ret; \
458     })
459 IM_API IM_STATUS impalette_t(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync);
460 
461 /*
462  * translate
463  *
464  * @param src
465  * @param dst
466  * @param x
467  * @param y
468  * @param sync
469  *      wait until operation complete
470  *
471  * @returns success or else negative error code.
472  */
473 #define imtranslate(src, dst, x, y, ...) \
474     ({ \
475         IM_STATUS __ret = IM_STATUS_SUCCESS; \
476         int __args[] = {__VA_ARGS__}; \
477         int __argc = sizeof(__args)/sizeof(int); \
478         if (__argc == 0) { \
479             __ret = imtranslate_t(src, dst, x, y, 1); \
480         } else if (__argc == 1){ \
481             __ret = imtranslate_t(src, dst, x, y, (int)__args[RGA_GET_MIN(__argc, 0)]); \
482         } else { \
483             __ret = IM_STATUS_INVALID_PARAM; \
484             printf("invalid parameter\n"); \
485         } \
486         __ret; \
487     })
488 IM_API IM_STATUS imtranslate_t(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync);
489 
490 /*
491  * copy
492  *
493  * @param src
494  * @param dst
495  * @param sync
496  *      wait until operation complete
497  *
498  * @returns success or else negative error code.
499  */
500 #define imcopy(src, dst, ...) \
501     ({ \
502         IM_STATUS __ret = IM_STATUS_SUCCESS; \
503         int __args[] = {__VA_ARGS__}; \
504         int __argc = sizeof(__args)/sizeof(int); \
505         if (__argc == 0) { \
506             __ret = imcopy_t(src, dst, 1); \
507         } else if (__argc == 1){ \
508             __ret = imcopy_t(src, dst, (int)__args[RGA_GET_MIN(__argc, 0)]); \
509         } else { \
510             __ret = IM_STATUS_INVALID_PARAM; \
511             printf("invalid parameter\n"); \
512         } \
513         __ret; \
514     })
515 
516 IM_API IM_STATUS imcopy_t(const rga_buffer_t src, rga_buffer_t dst, int sync);
517 
518 /*
519  * blend (SRC + DST -> DST or SRCA + SRCB -> DST)
520  *
521  * @param srcA
522  * @param srcB can be NULL.
523  * @param dst
524  * @param mode
525  *      IM_ALPHA_BLEND_MODE
526  * @param sync
527  *      wait until operation complete
528  *
529  * @returns success or else negative error code.
530  */
531 #define imblend(srcA, dst, ...) \
532     ({ \
533         IM_STATUS __ret = IM_STATUS_SUCCESS; \
534         rga_buffer_t srcB; \
535         memset(&srcB, 0x00, sizeof(rga_buffer_t)); \
536         int __args[] = {__VA_ARGS__}; \
537         int __argc = sizeof(__args)/sizeof(int); \
538         if (__argc == 0) { \
539             __ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
540         } else if (__argc == 1){ \
541             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
542         } else if (__argc == 2){ \
543             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
544         } else { \
545             __ret = IM_STATUS_INVALID_PARAM; \
546             printf("invalid parameter\n"); \
547         } \
548         __ret; \
549     })
550 #define imcomposite(srcA, srcB, dst, ...) \
551     ({ \
552         IM_STATUS __ret = IM_STATUS_SUCCESS; \
553         int __args[] = {__VA_ARGS__}; \
554         int __argc = sizeof(__args)/sizeof(int); \
555         if (__argc == 0) { \
556             __ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
557         } else if (__argc == 1){ \
558             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
559         } else if (__argc == 2){ \
560             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
561         } else { \
562             __ret = IM_STATUS_INVALID_PARAM; \
563             printf("invalid parameter\n"); \
564         } \
565         __ret; \
566     })
567 IM_API IM_STATUS imblend_t(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode, int sync);
568 
569 /*
570  * color key
571  *
572  * @param src
573  * @param dst
574  * @param colorkey_range
575  *      max color
576  *      min color
577  * @param sync
578  *      wait until operation complete
579  *
580  * @returns success or else negative error code.
581  */
582 #define imcolorkey(src, dst, range, ...) \
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 = imcolorkey_t(src, dst, range, IM_ALPHA_COLORKEY_NORMAL, 1); \
589         } else if (__argc == 1){ \
590             __ret = imcolorkey_t(src, dst, range, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
591         } else if (__argc == 2){ \
592             __ret = imcolorkey_t(src, dst, range, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
593         } else { \
594             __ret = IM_STATUS_INVALID_PARAM; \
595             printf("invalid parameter\n"); \
596         } \
597         __ret; \
598     })
599 IM_API IM_STATUS imcolorkey_t(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode, int sync);
600 
601 /*
602  * format convert
603  *
604  * @param src
605  * @param dst
606  * @param sfmt
607  * @param dfmt
608  * @param mode
609  *      color space mode: IM_COLOR_SPACE_MODE
610  * @param sync
611  *      wait until operation complete
612  *
613  * @returns success or else negative error code.
614  */
615 #define imcvtcolor(src, dst, sfmt, dfmt, ...) \
616     ({ \
617         IM_STATUS __ret = IM_STATUS_SUCCESS; \
618         int __args[] = {__VA_ARGS__}; \
619         int __argc = sizeof(__args)/sizeof(int); \
620         if (__argc == 0) { \
621             __ret = imcvtcolor_t(src, dst, sfmt, dfmt, IM_COLOR_SPACE_DEFAULT, 1); \
622         } else if (__argc == 1){ \
623             __ret = imcvtcolor_t(src, dst, sfmt, dfmt, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
624         } else if (__argc == 2){ \
625             __ret = imcvtcolor_t(src, dst, sfmt, dfmt, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
626         } else { \
627             __ret = IM_STATUS_INVALID_PARAM; \
628             printf("invalid parameter\n"); \
629         } \
630         __ret; \
631     })
632 
633 IM_API IM_STATUS imcvtcolor_t(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode, int sync);
634 
635 /*
636  * nn quantize
637  *
638  * @param src
639  * @param dst
640  * @param nninfo
641  * @param sync
642  *      wait until operation complete
643  *
644  * @returns success or else negative error code.
645  */
646 #define imquantize(src, dst, nn_info, ...) \
647     ({ \
648         IM_STATUS __ret = IM_STATUS_SUCCESS; \
649         int __args[] = {__VA_ARGS__}; \
650         int __argc = sizeof(__args)/sizeof(int); \
651         if (__argc == 0) { \
652             __ret = imquantize_t(src, dst, nn_info, 1); \
653         } else if (__argc == 1){ \
654             __ret = imquantize_t(src, dst, nn_info, (int)__args[RGA_GET_MIN(__argc, 0)]); \
655         } else { \
656             __ret = IM_STATUS_INVALID_PARAM; \
657             printf("invalid parameter\n"); \
658         } \
659         __ret; \
660     })
661 
662 IM_API IM_STATUS imquantize_t(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync);
663 
664 /*
665  * ROP
666  *
667  * @param src
668  * @param dst
669  * @param rop_code
670  * @param sync
671  *      wait until operation complete
672  *
673  * @returns success or else negative error code.
674  */
675 #define imrop(src, dst, rop_code, ...) \
676     ({ \
677         IM_STATUS __ret = IM_STATUS_SUCCESS; \
678         int __args[] = {__VA_ARGS__}; \
679         int __argc = sizeof(__args)/sizeof(int); \
680         if (__argc == 0) { \
681             __ret = imrop_t(src, dst, rop_code, 1); \
682         } else if (__argc == 1){ \
683             __ret = imrop_t(src, dst, rop_code, (int)__args[RGA_GET_MIN(__argc, 0)]); \
684         } else { \
685             __ret = IM_STATUS_INVALID_PARAM; \
686             printf("invalid parameter\n"); \
687         } \
688         __ret; \
689     })
690 IM_API IM_STATUS imrop_t(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync);
691 
692 /*
693  * MOSAIC
694  *
695  * @param src
696  * @param dst
697  * @param mosaic_mode
698  * @param sync
699  *      wait until operation complete
700  *
701  * @returns success or else negative error code.
702  */
703 IM_API IM_STATUS immosaic(const rga_buffer_t image, im_rect rect, int mosaic_mode, int sync);
704 
705 /*
706  * OSD
707  *
708  * @param osd
709  *      osd block
710  * @param dst
711  *      background image
712  * @param osd_rect
713  * @param osd_config
714  *      osd mode config
715  * @param sync
716  *      wait until operation complete
717  *
718  * @returns success or else negative error code.
719  */
720 IM_API IM_STATUS imosd(const rga_buffer_t osd,const rga_buffer_t dst,
721                        const im_rect osd_rect, im_osd_t *osd_config, int sync);
722 
723 /*
724  * process
725  *
726  * @param src
727  * @param dst
728  * @param usage
729  * @param ...
730  *      wait until operation complete
731  *
732  * @returns success or else negative error code.
733  */
734 IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
735                         im_rect srect, im_rect drect, im_rect prect, int usage);
736 
737 /*
738  * block until all execution is complete
739  *
740  * @returns success or else negative error code.
741  */
742 IM_API IM_STATUS imsync(int out_fence_fd);
743 
744 /*
745  * config
746  *
747  * @param name
748  *      enum IM_CONFIG_NAME
749  * @param value
750  *
751  * @returns success or else negative error code.
752  */
753 IM_API IM_STATUS imconfig(IM_CONFIG_NAME name, uint64_t value);
754 
755 IM_API im_ctx_id_t imbegin(uint32_t flags);
756 
757 IM_API IM_STATUS imcancel(im_ctx_id_t id);
758 
759 #ifdef __cplusplus
760 }
761 #endif
762 #endif /* _im2d_h_ */
763 
764