xref: /OK3568_Linux_fs/external/rknpu2/examples/3rdparty/rga/RK356X/include/im2d_single.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
3  * Authors:
4  *  Cerf Yu <cerf.yu@rock-chips.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://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,
14  * WITHOUT 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 #ifndef _im2d_single_h_
19 #define _im2d_single_h_
20 
21 #include "im2d_type.h"
22 
23 #ifdef __cplusplus
24 
25 /**
26  * copy
27  *
28  * @param src
29  *      The input source image.
30  * @param dst
31  *      The output destination image.
32  * @param sync
33  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
34  * @param release_fence_fd
35  *      When 'sync == 0', the fence_fd used to identify the current job state
36  *
37  * @returns success or else negative error code.
38  */
39 IM_API IM_STATUS imcopy(const rga_buffer_t src, rga_buffer_t dst, int sync = 1, int *release_fence_fd = NULL);
40 
41 /**
42  * Resize
43  *
44  * @param src
45  *      The input source image.
46  * @param dst
47  *      The output destination image.
48  * @param fx
49  *      X-direction resize factor.
50  * @param fy
51  *      X-direction resize factor.
52  * @param interpolation
53  *      Interpolation formula(Only RGA1 support).
54  * @param sync
55  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
56  * @param release_fence_fd
57  *      When 'sync == 0', the fence_fd used to identify the current job state
58  *
59  * @returns success or else negative error code.
60  */
61 IM_API IM_STATUS imresize(const rga_buffer_t src, rga_buffer_t dst, double fx = 0, double fy = 0, int interpolation = 0, int sync = 1, int *release_fence_fd = NULL);
62 
63 /**
64  * Crop
65  *
66  * @param src
67  *      The input source image.
68  * @param dst
69  *      The output destination image.
70  * @param rect
71  *      The rectangle on the source image that needs to be cropped.
72  * @param sync
73  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
74  * @param release_fence_fd
75  *      When 'sync == 0', the fence_fd used to identify the current job state
76  *
77  * @returns success or else negative error code.
78  */
79 IM_API IM_STATUS imcrop(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync = 1, int *release_fence_fd = NULL);
80 
81 /**
82  * translate
83  *
84  * @param src
85  *      The input source image.
86  * @param dst
87  *      The output destination image.
88  * @param x
89  *      Output the coordinates of the starting point in the X-direction of the destination image.
90  * @param y
91  *      Output the coordinates of the starting point in the Y-direction of the destination image.
92  * @param sync
93  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
94  * @param release_fence_fd
95  *      When 'sync == 0', the fence_fd used to identify the current job state
96  *
97  * @returns success or else negative error code.
98  */
99 IM_API IM_STATUS imtranslate(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync = 1, int *release_fence_fd = NULL);
100 
101 /**
102  * format convert
103  *
104  * @param src
105  *      The input source image.
106  * @param dst
107  *      The output destination image.
108  * @param sfmt
109  *      The source image format.
110  * @param dfmt
111  *      The destination image format.
112  * @param mode
113  *      color space mode:
114  *          IM_YUV_TO_RGB_BT601_LIMIT
115  *          IM_YUV_TO_RGB_BT601_FULL
116  *          IM_YUV_TO_RGB_BT709_LIMIT
117  *          IM_RGB_TO_YUV_BT601_FULL
118  *          IM_RGB_TO_YUV_BT601_LIMIT
119  *          IM_RGB_TO_YUV_BT709_LIMIT
120  * @param sync
121  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
122  * @param release_fence_fd
123  *      When 'sync == 0', the fence_fd used to identify the current job state
124  *
125  * @returns success or else negative error code.
126  */
127 IM_API IM_STATUS imcvtcolor(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode = IM_COLOR_SPACE_DEFAULT, int sync = 1, int *release_fence_fd = NULL);
128 
129 /**
130  * rotation
131  *
132  * @param src
133  *      The input source image.
134  * @param dst
135  *      The output destination image.
136  * @param rotation
137  *      IM_HAL_TRANSFORM_ROT_90
138  *      IM_HAL_TRANSFORM_ROT_180
139  *      IM_HAL_TRANSFORM_ROT_270
140  * @param sync
141  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
142  * @param release_fence_fd
143  *      When 'sync == 0', the fence_fd used to identify the current job state
144  *
145  * @returns success or else negative error code.
146  */
147 IM_API IM_STATUS imrotate(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync = 1, int *release_fence_fd = NULL);
148 
149 /**
150  * flip
151  *
152  * @param src
153  *      The input source image.
154  * @param dst
155  *      The output destination image.
156  * @param mode
157  *      IM_HAL_TRANSFORM_FLIP_H
158  *      IM_HAL_TRANSFORM_FLIP_V
159  * @param sync
160  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
161  * @param release_fence_fd
162  *      When 'sync == 0', the fence_fd used to identify the current job state
163  *
164  * @returns success or else negative error code.
165  */
166 IM_API IM_STATUS imflip(const rga_buffer_t src, rga_buffer_t dst, int mode, int sync = 1, int *release_fence_fd = NULL);
167 
168 /**
169  * 2-channel blend (SRC + DST -> DST or SRCA + SRCB -> DST)
170  *
171  * @param fg_image
172  *      The foreground image.
173  * @param bg_image
174  *      The background image, which is also the output destination image.
175  * @param mode
176  *      Port-Duff mode:
177  *          IM_ALPHA_BLEND_SRC
178  *          IM_ALPHA_BLEND_DST
179  *          IM_ALPHA_BLEND_SRC_OVER
180  *          IM_ALPHA_BLEND_DST_OVER
181  * @param sync
182  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
183  * @param release_fence_fd
184  *      When 'sync == 0', the fence_fd used to identify the current job state
185  *
186  * @returns success or else negative error code.
187  */
188 IM_API IM_STATUS imblend(const rga_buffer_t fd_image, rga_buffer_t bg_image, int mode = IM_ALPHA_BLEND_SRC_OVER, int sync = 1, int *release_fence_fd = NULL);
189 
190 /**
191  * 3-channel blend (SRC + DST -> DST or SRCA + SRCB -> DST)
192  *
193  * @param fg_image
194  *      The foreground image.
195  * @param bg_image
196  *      The background image.
197  * @param output_image
198  *      The output destination image.
199  * @param mode
200  *      Port-Duff mode:
201  *          IM_ALPHA_BLEND_SRC
202  *          IM_ALPHA_BLEND_DST
203  *          IM_ALPHA_BLEND_SRC_OVER
204  *          IM_ALPHA_BLEND_DST_OVER
205  * @param sync
206  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
207  * @param release_fence_fd
208  *      When 'sync == 0', the fence_fd used to identify the current job state
209  *
210  * @returns success or else negative error code.
211  */
212 IM_API IM_STATUS imcomposite(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode = IM_ALPHA_BLEND_SRC_OVER, int sync = 1, int *release_fence_fd = NULL);
213 
214 /**
215  * color key
216  *
217  * @param fg_image
218  *      The foreground image.
219  * @param bg_image
220  *      The background image, which is also the output destination image.
221  * @param colorkey_range
222  *      The range of color key.
223  * @param sync
224  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
225  *
226  * @returns success or else negative error code.
227  */
228 IM_API IM_STATUS imcolorkey(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode = IM_ALPHA_COLORKEY_NORMAL, int sync = 1, int *release_fence_fd = NULL);
229 
230 /**
231  * OSD
232  *
233  * @param osd
234  *      The osd text block.
235  * @param dst
236  *      The background image.
237  * @param osd_rect
238  *      The rectangle on the source image that needs to be OSD.
239  * @param osd_config
240  *      osd mode configuration.
241  * @param sync
242  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
243  *
244  * @returns success or else negative error code.
245  */
246 IM_API IM_STATUS imosd(const rga_buffer_t osd,const rga_buffer_t dst,
247                        const im_rect osd_rect, im_osd_t *osd_config,
248                        int sync = 1, int *release_fence_fd = NULL);
249 
250 /**
251  * nn quantize
252  *
253  * @param src
254  *      The input source image.
255  * @param dst
256  *      The output destination image.
257  * @param nninfo
258  *      nn configuration
259  * @param sync
260  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
261  *
262  * @returns success or else negative error code.
263  */
264 IM_API IM_STATUS imquantize(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync = 1, int *release_fence_fd = NULL);
265 
266 /**
267  * ROP
268  *
269  * @param src
270  *      The input source image.
271  * @param dst
272  *      The output destination image.
273  * @param rop_code
274  *      The ROP opcode.
275  * @param sync
276  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
277  *
278  * @returns success or else negative error code.
279  */
280 IM_API IM_STATUS imrop(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync = 1, int *release_fence_fd = NULL);
281 
282 /**
283  * fill/reset/draw
284  *
285  * @param dst
286  *      The output destination image.
287  * @param rect
288  *      The rectangle on the source image that needs to be filled with color.
289  * @param color
290  *      The fill color value.
291  * @param sync
292  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
293  *
294  * @returns success or else negative error code.
295  */
296 IM_API IM_STATUS imfill(rga_buffer_t dst, im_rect rect, int color, int sync = 1, int *release_fence_fd = NULL);
297 
298 /**
299  * fill array
300  *
301  * @param dst
302  *      The output destination image.
303  * @param rect_array
304  *      The rectangle arrays on the source image that needs to be filled with color.
305  * @param array_size
306  *      The size of rectangular area arrays.
307  * @param color
308  *      The fill color value.
309  * @param sync
310  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
311  *
312  * @returns success or else negative error code.
313  */
314 IM_API IM_STATUS imfillArray(rga_buffer_t dst, im_rect *rect_array, int array_size, uint32_t color, int sync = 1, int *release_fence_fd = NULL);
315 
316 /**
317  * fill rectangle
318  *
319  * @param dst
320  *      The output destination image.
321  * @param rect
322  *      The rectangle on the source image that needs to be filled with color.
323  * @param color
324  *      The fill color value.
325  * @param thickness
326  *      Thickness of lines that make up the rectangle. Negative values, like -1,
327  *      mean that the function has to draw a filled rectangle.
328  * @param sync
329  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
330  *
331  * @returns success or else negative error code.
332  */
333 IM_API IM_STATUS imrectangle(rga_buffer_t dst, im_rect rect,
334                              uint32_t color, int thickness,
335                              int sync = 1, int *release_fence_fd = NULL);
336 
337 /**
338  * fill rectangle array
339  *
340  * @param dst
341  *      The output destination image.
342  * @param rect_array
343  *      The rectangle arrays on the source image that needs to be filled with color.
344  * @param array_size
345  *      The size of rectangular area arrays.
346  * @param color
347  *      The fill color value.
348  * @param thickness
349  *      Thickness of lines that make up the rectangle. Negative values, like -1,
350  *      mean that the function has to draw a filled rectangle.
351  * @param sync
352  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
353  *
354  * @returns success or else negative error code.
355  */
356 IM_API IM_STATUS imrectangleArray(rga_buffer_t dst, im_rect *rect_array, int array_size,
357                                    uint32_t color, int thickness,
358                                    int sync = 1, int *release_fence_fd = NULL);
359 
360 /**
361  * MOSAIC
362  *
363  * @param image
364  *      The output destination image.
365  * @param rect
366  *      The rectangle on the source image that needs to be mosaicked.
367  * @param mosaic_mode
368  *      mosaic block width configuration:
369  *          IM_MOSAIC_8
370  *          IM_MOSAIC_16
371  *          IM_MOSAIC_32
372  *          IM_MOSAIC_64
373  *          IM_MOSAIC_128
374  * @param sync
375  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
376  *
377  * @returns success or else negative error code.
378  */
379 IM_API IM_STATUS immosaic(const rga_buffer_t image, im_rect rect, int mosaic_mode, int sync = 1, int *release_fence_fd = NULL);
380 
381 /**
382  * MOSAIC array
383  *
384  * @param image
385  *      The output destination image.
386  * @param rect_array
387  *      The rectangle arrays on the source image that needs to be filled with color.
388  * @param array_size
389  *      The size of rectangular area arrays.
390  * @param mosaic_mode
391  *      mosaic block width configuration:
392  *          IM_MOSAIC_8
393  *          IM_MOSAIC_16
394  *          IM_MOSAIC_32
395  *          IM_MOSAIC_64
396  *          IM_MOSAIC_128
397  * @param sync
398  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
399  *
400  * @returns success or else negative error code.
401  */
402 IM_API IM_STATUS immosaicArray(const rga_buffer_t image, im_rect *rect_array, int array_size, int mosaic_mode, int sync = 1, int *release_fence_fd = NULL);
403 
404 /**
405  * palette
406  *
407  * @param src
408  *      The input source image.
409  * @param dst
410  *      The output destination image.
411  * @param lut
412  *      The LUT table.
413  * @param sync
414  *      When 'sync == 1', wait for the operation to complete and return, otherwise return directly.
415  *
416  * @returns success or else negative error code.
417  */
418 IM_API IM_STATUS impalette(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync = 1, int *release_fence_fd = NULL);
419 
420 /**
421  * process for single task mode
422  *
423  * @param src
424  *      The input source image and is also the foreground image in blend.
425  * @param dst
426  *      The output destination image and is also the foreground image in blend.
427  * @param pat
428  *      The foreground image, or a LUT table.
429  * @param srect
430  *      The rectangle on the src channel image that needs to be processed.
431  * @param drect
432  *      The rectangle on the dst channel image that needs to be processed.
433  * @param prect
434  *      The rectangle on the pat channel image that needs to be processed.
435  * @param opt
436  *      The image processing options configuration.
437  * @param usage
438  *      The image processing usage.
439  *
440  * @returns success or else negative error code.
441  */
442 IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
443                            im_rect srect, im_rect drect, im_rect prect,
444                            int acquire_fence_fd, int *release_fence_fd,
445                            im_opt_t *opt_ptr, int usage);
446 
447 /**
448  * make border
449  *
450  * @param src
451  *      The input source image.
452  * @param dst
453  *      The output destination image.
454  * @param top
455  *      the top pixels
456  * @param bottom
457  *      the bottom pixels
458  * @param left
459  *      the left pixels
460  * @param right
461  *      the right pixels
462  * @param border_type
463  *      Border type.
464  * @param value
465  *      The pixel value at which the border is filled.
466  *
467  * @returns success or else negative error code.
468  */
469 IM_API IM_STATUS immakeBorder(rga_buffer_t src, rga_buffer_t dst,
470                               int top, int bottom, int left, int right,
471                               int border_type, int value = 0,
472                               int sync = 1, int acquir_fence_fd = -1, int *release_fence_fd = NULL);
473 
474 #endif /* #ifdef __cplusplus */
475 
476 IM_C_API IM_STATUS immosaic(const rga_buffer_t image, im_rect rect, int mosaic_mode, int sync);
477 IM_C_API IM_STATUS imosd(const rga_buffer_t osd,const rga_buffer_t dst,
478                          const im_rect osd_rect, im_osd_t *osd_config, int sync);
479 IM_C_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
480                              im_rect srect, im_rect drect, im_rect prect, int usage);
481 
482 /* Start: Symbols reserved for compatibility with macro functions */
483 IM_C_API IM_STATUS imcopy_t(const rga_buffer_t src, rga_buffer_t dst, int sync);
484 IM_C_API IM_STATUS imresize_t(const rga_buffer_t src, rga_buffer_t dst, double fx, double fy, int interpolation, int sync);
485 IM_C_API IM_STATUS imcrop_t(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync);
486 IM_C_API IM_STATUS imtranslate_t(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync);
487 IM_C_API IM_STATUS imcvtcolor_t(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode, int sync);
488 IM_C_API IM_STATUS imrotate_t(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync);
489 IM_C_API IM_STATUS imflip_t (const rga_buffer_t src, rga_buffer_t dst, int mode, int sync);
490 IM_C_API IM_STATUS imblend_t(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode, int sync);
491 IM_C_API IM_STATUS imcolorkey_t(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode, int sync);
492 IM_C_API IM_STATUS imquantize_t(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync);
493 IM_C_API IM_STATUS imrop_t(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync);
494 IM_C_API IM_STATUS imfill_t(rga_buffer_t dst, im_rect rect, int color, int sync);
495 IM_C_API IM_STATUS impalette_t(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync);
496 /* End: Symbols reserved for compatibility with macro functions */
497 
498 #ifndef __cplusplus
499 
500 #define RGA_GET_MIN(n1, n2) ((n1) < (n2) ? (n1) : (n2))
501 
502 /**
503  * copy
504  *
505  * @param src
506  * @param dst
507  * @param sync
508  *      wait until operation complete
509  *
510  * @returns success or else negative error code.
511  */
512 #define imcopy(src, dst, ...) \
513     ({ \
514         IM_STATUS __ret = IM_STATUS_SUCCESS; \
515         int __args[] = {__VA_ARGS__}; \
516         int __argc = sizeof(__args)/sizeof(int); \
517         if (__argc == 0) { \
518             __ret = imcopy_t(src, dst, 1); \
519         } else if (__argc == 1){ \
520             __ret = imcopy_t(src, dst, (int)__args[RGA_GET_MIN(__argc, 0)]); \
521         } else { \
522             __ret = IM_STATUS_INVALID_PARAM; \
523             printf("invalid parameter\n"); \
524         } \
525         __ret; \
526     })
527 
528 /**
529  * Resize
530  *
531  * @param src
532  * @param dst
533  * @param fx
534  * @param fy
535  * @param interpolation
536  * @param sync
537  *      wait until operation complete
538  *
539  * @returns success or else negative error code.
540  */
541 #define imresize(src, dst, ...) \
542     ({ \
543         IM_STATUS __ret = IM_STATUS_SUCCESS; \
544         double __args[] = {__VA_ARGS__}; \
545         int __argc = sizeof(__args)/sizeof(double); \
546         if (__argc == 0) { \
547             __ret = imresize_t(src, dst, 0, 0, INTER_LINEAR, 1); \
548         } else if (__argc == 2){ \
549             __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], INTER_LINEAR, 1); \
550         } else if (__argc == 3){ \
551             __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); \
552         } else if (__argc == 4){ \
553             __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)]); \
554         } else { \
555             __ret = IM_STATUS_INVALID_PARAM; \
556             printf("invalid parameter\n"); \
557         } \
558         __ret; \
559     })
560 
561 #define impyramid(src, dst, direction) \
562         imresize_t(src, \
563                    dst, \
564                    direction == IM_UP_SCALE ? 0.5 : 2, \
565                    direction == IM_UP_SCALE ? 0.5 : 2, \
566                    INTER_LINEAR, 1)
567 
568 /**
569  * format convert
570  *
571  * @param src
572  * @param dst
573  * @param sfmt
574  * @param dfmt
575  * @param mode
576  *      color space mode: IM_COLOR_SPACE_MODE
577  * @param sync
578  *      wait until operation complete
579  *
580  * @returns success or else negative error code.
581  */
582 #define imcvtcolor(src, dst, sfmt, dfmt, ...) \
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 = imcvtcolor_t(src, dst, sfmt, dfmt, IM_COLOR_SPACE_DEFAULT, 1); \
589         } else if (__argc == 1){ \
590             __ret = imcvtcolor_t(src, dst, sfmt, dfmt, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
591         } else if (__argc == 2){ \
592             __ret = imcvtcolor_t(src, dst, sfmt, dfmt, (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 
600 /**
601  * Crop
602  *
603  * @param src
604  * @param dst
605  * @param rect
606  * @param sync
607  *      wait until operation complete
608  *
609  * @returns success or else negative error code.
610  */
611 #define imcrop(src, dst, rect, ...) \
612     ({ \
613         IM_STATUS __ret = IM_STATUS_SUCCESS; \
614         int __args[] = {__VA_ARGS__}; \
615         int __argc = sizeof(__args)/sizeof(int); \
616         if (__argc == 0) { \
617             __ret = imcrop_t(src, dst, rect, 1); \
618         } else if (__argc == 1){ \
619             __ret = imcrop_t(src, dst, rect, (int)__args[RGA_GET_MIN(__argc, 0)]); \
620         } else { \
621             __ret = IM_STATUS_INVALID_PARAM; \
622             printf("invalid parameter\n"); \
623         } \
624         __ret; \
625     })
626 
627 /**
628  * translate
629  *
630  * @param src
631  * @param dst
632  * @param x
633  * @param y
634  * @param sync
635  *      wait until operation complete
636  *
637  * @returns success or else negative error code.
638  */
639 #define imtranslate(src, dst, x, y, ...) \
640     ({ \
641         IM_STATUS __ret = IM_STATUS_SUCCESS; \
642         int __args[] = {__VA_ARGS__}; \
643         int __argc = sizeof(__args)/sizeof(int); \
644         if (__argc == 0) { \
645             __ret = imtranslate_t(src, dst, x, y, 1); \
646         } else if (__argc == 1){ \
647             __ret = imtranslate_t(src, dst, x, y, (int)__args[RGA_GET_MIN(__argc, 0)]); \
648         } else { \
649             __ret = IM_STATUS_INVALID_PARAM; \
650             printf("invalid parameter\n"); \
651         } \
652         __ret; \
653     })
654 
655 /**
656  * rotation
657  *
658  * @param src
659  * @param dst
660  * @param rotation
661  *      IM_HAL_TRANSFORM_ROT_90
662  *      IM_HAL_TRANSFORM_ROT_180
663  *      IM_HAL_TRANSFORM_ROT_270
664  * @param sync
665  *      wait until operation complete
666  *
667  * @returns success or else negative error code.
668  */
669 #define imrotate(src, dst, rotation, ...) \
670     ({ \
671         IM_STATUS __ret = IM_STATUS_SUCCESS; \
672         int __args[] = {__VA_ARGS__}; \
673         int __argc = sizeof(__args)/sizeof(int); \
674         if (__argc == 0) { \
675             __ret = imrotate_t(src, dst, rotation, 1); \
676         } else if (__argc == 1){ \
677             __ret = imrotate_t(src, dst, rotation, (int)__args[RGA_GET_MIN(__argc, 0)]); \
678         } else { \
679             __ret = IM_STATUS_INVALID_PARAM; \
680             printf("invalid parameter\n"); \
681         } \
682         __ret; \
683     })
684 
685 
686 /**
687  * flip
688  *
689  * @param src
690  * @param dst
691  * @param mode
692  *      IM_HAL_TRANSFORM_FLIP_H
693  *      IM_HAL_TRANSFORM_FLIP_V
694  * @param sync
695  *      wait until operation complete
696  *
697  * @returns success or else negative error code.
698  */
699 #define imflip(src, dst, mode, ...) \
700     ({ \
701         IM_STATUS __ret = IM_STATUS_SUCCESS; \
702         int __args[] = {__VA_ARGS__}; \
703         int __argc = sizeof(__args)/sizeof(int); \
704         if (__argc == 0) { \
705             __ret = imflip_t(src, dst, mode, 1); \
706         } else if (__argc == 1){ \
707             __ret = imflip_t(src, dst, mode, (int)__args[RGA_GET_MIN(__argc, 0)]); \
708         } else { \
709             __ret = IM_STATUS_INVALID_PARAM; \
710             printf("invalid parameter\n"); \
711         } \
712         __ret; \
713     })
714 
715 /**
716  * blend (SRC + DST -> DST or SRCA + SRCB -> DST)
717  *
718  * @param srcA
719  * @param srcB can be NULL.
720  * @param dst
721  * @param mode
722  *      IM_ALPHA_BLEND_MODE
723  * @param sync
724  *      wait until operation complete
725  *
726  * @returns success or else negative error code.
727  */
728 #define imblend(srcA, dst, ...) \
729     ({ \
730         IM_STATUS __ret = IM_STATUS_SUCCESS; \
731         rga_buffer_t srcB; \
732         memset(&srcB, 0x00, sizeof(rga_buffer_t)); \
733         int __args[] = {__VA_ARGS__}; \
734         int __argc = sizeof(__args)/sizeof(int); \
735         if (__argc == 0) { \
736             __ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
737         } else if (__argc == 1){ \
738             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
739         } else if (__argc == 2){ \
740             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
741         } else { \
742             __ret = IM_STATUS_INVALID_PARAM; \
743             printf("invalid parameter\n"); \
744         } \
745         __ret; \
746     })
747 #define imcomposite(srcA, srcB, dst, ...) \
748     ({ \
749         IM_STATUS __ret = IM_STATUS_SUCCESS; \
750         int __args[] = {__VA_ARGS__}; \
751         int __argc = sizeof(__args)/sizeof(int); \
752         if (__argc == 0) { \
753             __ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
754         } else if (__argc == 1){ \
755             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
756         } else if (__argc == 2){ \
757             __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
758         } else { \
759             __ret = IM_STATUS_INVALID_PARAM; \
760             printf("invalid parameter\n"); \
761         } \
762         __ret; \
763     })
764 
765 /**
766  * color key
767  *
768  * @param src
769  * @param dst
770  * @param colorkey_range
771  *      max color
772  *      min color
773  * @param sync
774  *      wait until operation complete
775  *
776  * @returns success or else negative error code.
777  */
778 #define imcolorkey(src, dst, range, ...) \
779     ({ \
780         IM_STATUS __ret = IM_STATUS_SUCCESS; \
781         int __args[] = {__VA_ARGS__}; \
782         int __argc = sizeof(__args)/sizeof(int); \
783         if (__argc == 0) { \
784             __ret = imcolorkey_t(src, dst, range, IM_ALPHA_COLORKEY_NORMAL, 1); \
785         } else if (__argc == 1){ \
786             __ret = imcolorkey_t(src, dst, range, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \
787         } else if (__argc == 2){ \
788             __ret = imcolorkey_t(src, dst, range, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \
789         } else { \
790             __ret = IM_STATUS_INVALID_PARAM; \
791             printf("invalid parameter\n"); \
792         } \
793         __ret; \
794     })
795 
796 /**
797  * nn quantize
798  *
799  * @param src
800  * @param dst
801  * @param nninfo
802  * @param sync
803  *      wait until operation complete
804  *
805  * @returns success or else negative error code.
806  */
807 #define imquantize(src, dst, nn_info, ...) \
808     ({ \
809         IM_STATUS __ret = IM_STATUS_SUCCESS; \
810         int __args[] = {__VA_ARGS__}; \
811         int __argc = sizeof(__args)/sizeof(int); \
812         if (__argc == 0) { \
813             __ret = imquantize_t(src, dst, nn_info, 1); \
814         } else if (__argc == 1){ \
815             __ret = imquantize_t(src, dst, nn_info, (int)__args[RGA_GET_MIN(__argc, 0)]); \
816         } else { \
817             __ret = IM_STATUS_INVALID_PARAM; \
818             printf("invalid parameter\n"); \
819         } \
820         __ret; \
821     })
822 
823 
824 /**
825  * ROP
826  *
827  * @param src
828  * @param dst
829  * @param rop_code
830  * @param sync
831  *      wait until operation complete
832  *
833  * @returns success or else negative error code.
834  */
835 #define imrop(src, dst, rop_code, ...) \
836     ({ \
837         IM_STATUS __ret = IM_STATUS_SUCCESS; \
838         int __args[] = {__VA_ARGS__}; \
839         int __argc = sizeof(__args)/sizeof(int); \
840         if (__argc == 0) { \
841             __ret = imrop_t(src, dst, rop_code, 1); \
842         } else if (__argc == 1){ \
843             __ret = imrop_t(src, dst, rop_code, (int)__args[RGA_GET_MIN(__argc, 0)]); \
844         } else { \
845             __ret = IM_STATUS_INVALID_PARAM; \
846             printf("invalid parameter\n"); \
847         } \
848         __ret; \
849     })
850 
851 /**
852  * fill/reset/draw
853  *
854  * @param src
855  * @param dst
856  * @param rect
857  * @param color
858  * @param sync
859  *      wait until operation complete
860  *
861  * @returns success or else negative error code.
862  */
863 #define imfill(buf, rect, color, ...) \
864     ({ \
865         IM_STATUS __ret = IM_STATUS_SUCCESS; \
866         int __args[] = {__VA_ARGS__}; \
867         int __argc = sizeof(__args)/sizeof(int); \
868         if (__argc == 0) { \
869             __ret = imfill_t(buf, rect, color, 1); \
870         } else if (__argc == 1){ \
871             __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \
872         } else { \
873             __ret = IM_STATUS_INVALID_PARAM; \
874             printf("invalid parameter\n"); \
875         } \
876         __ret; \
877     })
878 
879 #define imreset(buf, rect, color, ...) \
880     ({ \
881         IM_STATUS __ret = IM_STATUS_SUCCESS; \
882         int __args[] = {__VA_ARGS__}; \
883         int __argc = sizeof(__args)/sizeof(int); \
884         if (__argc == 0) { \
885             __ret = imfill_t(buf, rect, color, 1); \
886         } else if (__argc == 1){ \
887             __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \
888         } else { \
889             __ret = IM_STATUS_INVALID_PARAM; \
890             printf("invalid parameter\n"); \
891         } \
892         __ret; \
893     })
894 
895 #define imdraw(buf, rect, color, ...) \
896     ({ \
897         IM_STATUS __ret = IM_STATUS_SUCCESS; \
898         int __args[] = {__VA_ARGS__}; \
899         int __argc = sizeof(__args)/sizeof(int); \
900         if (__argc == 0) { \
901             __ret = imfill_t(buf, rect, color, 1); \
902         } else if (__argc == 1){ \
903             __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \
904         } else { \
905             __ret = IM_STATUS_INVALID_PARAM; \
906             printf("invalid parameter\n"); \
907         } \
908         __ret; \
909     })
910 
911 /**
912  * palette
913  *
914  * @param src
915  * @param dst
916  * @param lut
917  * @param sync
918  *      wait until operation complete
919  *
920  * @returns success or else negative error code.
921  */
922 #define impalette(src, dst, lut,  ...) \
923     ({ \
924         IM_STATUS __ret = IM_STATUS_SUCCESS; \
925         int __args[] = {__VA_ARGS__}; \
926         int __argc = sizeof(__args)/sizeof(int); \
927         if (__argc == 0) { \
928             __ret = impalette_t(src, dst, lut, 1); \
929         } else if (__argc == 1){ \
930             __ret = impalette_t(src, dst, lut, (int)__args[RGA_GET_MIN(__argc, 0)]); \
931         } else { \
932             __ret = IM_STATUS_INVALID_PARAM; \
933             printf("invalid parameter\n"); \
934         } \
935         __ret; \
936     })
937 /* End define IM2D macro API */
938 #endif
939 
940 #endif /* #ifndef _im2d_single_h_ */