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 
230 typedef struct im_nn {
231     int scale_r;                /* scaling factor on R channal */
232     int scale_g;                /* scaling factor on G channal */
233     int scale_b;                /* scaling factor on B channal */
234     int offset_r;               /* offset on R channal */
235     int offset_g;               /* offset on G channal */
236     int offset_b;               /* offset on B channal */
237 } im_nn_t;
238 
239 /* im_info definition */
240 typedef struct {
241     void* vir_addr;                     /* virtual address */
242     void* phy_addr;                     /* physical address */
243     int fd;                             /* shared fd */
244     int width;                          /* width */
245     int height;                         /* height */
246     int wstride;                        /* wstride */
247     int hstride;                        /* hstride */
248     int format;                         /* format */
249     int color_space_mode;               /* color_space_mode */
250     int color;                          /* color, used by color fill */
251     int global_alpha;                   /* global_alpha */
252     im_colorkey_range colorkey_range;   /* range value of color key */
253     im_nn_t nn;
254     int rop_code;
255 } rga_buffer_t;
256 
257 /*
258  * @return error message string
259  */
260 #define imStrError(...) \
261     ( { \
262         const char* err; \
263         int args[] = {__VA_ARGS__}; \
264         int argc = sizeof(args)/sizeof(int); \
265         if (argc == 0) { \
266             err = imStrError_t(IM_STATUS_INVALID_PARAM); \
267         } else if (argc == 1) { \
268             err = imStrError_t((IM_STATUS)args[0]); \
269         } else { \
270             err = ("Fatal error, imStrError() too many parameters\n"); \
271             printf("Fatal error, imStrError() too many parameters\n"); \
272         } \
273         err; \
274     })
275 IM_API const char* imStrError_t(IM_STATUS status);
276 
277 /*
278  * @return rga_buffer_t
279  */
280 #define wrapbuffer_virtualaddr(vir_addr, width, height, format, ...) \
281     ( { \
282         rga_buffer_t buffer; \
283         int args[] = {__VA_ARGS__}; \
284         int argc = sizeof(args)/sizeof(int); \
285         if (argc == 0) { \
286             buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, width, height, format); \
287         } else if (argc == 2) { \
288             buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, args[0], args[1], format); \
289         } else { \
290             printf("invalid parameter\n"); \
291         } \
292         buffer; \
293     })
294 
295 #define wrapbuffer_physicaladdr(phy_addr, width, height, format, ...) \
296     ( { \
297         rga_buffer_t buffer; \
298         int args[] = {__VA_ARGS__}; \
299         int argc = sizeof(args)/sizeof(int); \
300         if (argc == 0) { \
301             buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, width, height, format); \
302         } else if (argc == 2) { \
303             buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, args[0], args[1], format); \
304         } else { \
305             printf("invalid parameter\n"); \
306         } \
307         buffer; \
308     })
309 
310 #define wrapbuffer_fd(fd, width, height, format, ...) \
311     ( { \
312         rga_buffer_t buffer; \
313         int args[] = {__VA_ARGS__}; \
314         int argc = sizeof(args)/sizeof(int); \
315         if (argc == 0) { \
316             buffer = wrapbuffer_fd_t(fd, width, height, width, height, format); \
317         } else if (argc == 2) { \
318             buffer = wrapbuffer_fd_t(fd, width, height, args[0], args[1], format); \
319         } else { \
320             printf("invalid parameter\n"); \
321         } \
322         buffer; \
323     })
324 
325 IM_API rga_buffer_t wrapbuffer_virtualaddr_t(
326     void* vir_addr,
327     int width,
328     int height,
329     int wstride,
330     int hstride,
331     int format);
332 IM_API rga_buffer_t wrapbuffer_physicaladdr_t(void* phy_addr,
333     int width,
334     int height,
335     int wstride,
336     int hstride,
337     int format);
338 IM_API rga_buffer_t wrapbuffer_fd_t(int fd, int width, int height, int wstride, int hstride, int format);
339 
340 /*
341  * Get RGA basic information, supported resolution, supported format, etc.
342  *
343  * @param name
344  *      RGA_VENDOR
345  *      RGA_VERSION
346  *      RGA_MAX_INPUT
347  *      RGA_MAX_OUTPUT
348  *      RGA_INPUT_FORMAT
349  *      RGA_OUTPUT_FORMAT
350  *      RGA_EXPECTED
351  *      RGA_ALL
352  *
353  * @returns a usage describing properties of RGA.
354  */
355 IM_API IM_STATUS rga_get_info(rga_info_table_entry *return_table);
356 
357 /*
358  * Query RGA basic information, supported resolution, supported format, etc.
359  *
360  * @param name
361  *      RGA_VENDOR
362  *      RGA_VERSION
363  *      RGA_MAX_INPUT
364  *      RGA_MAX_OUTPUT
365  *      RGA_INPUT_FORMAT
366  *      RGA_OUTPUT_FORMAT
367  *      RGA_EXPECTED
368  *      RGA_ALL
369  *
370  * @returns a string describing properties of RGA.
371  */
372 IM_API const char* querystring(int name);
373 
374 /*
375  * check RGA basic information, supported resolution, supported format, etc.
376  *
377  * @param src
378  * @param dst
379  * @param src_rect
380  * @param dst_rect
381  * @param mode_usage
382  *
383  * @returns no error or else negative error code.
384  */
385 #define imcheck(src, dst, src_rect, dst_rect, ...) \
386     ( { \
387         IM_STATUS ret = IM_STATUS_NOERROR; \
388         rga_buffer_t pat; \
389         im_rect pat_rect; \
390         errno_t eok = memset_s(&pat, sizeof(rga_buffer_t), 0, sizeof(rga_buffer_t)); \
391         if (!eok) { \
392             printf("memset_s failed!\n"); \
393         } \
394         eok = memset_s(&pat_rect, sizeof(im_rect), 0, sizeof(im_rect)); \
395         if (!eok) { \
396             printf("memset_s failed!\n"); \
397         } \
398         int args[] = {__VA_ARGS__}; \
399         int argc = sizeof(args)/sizeof(int); \
400         if (argc == 0) { \
401             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \
402         } else if (argc == 1) { \
403             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, args[0]); \
404         } else { \
405             ret = IM_STATUS_FAILED; \
406             printf("check failed\n"); \
407         } \
408         ret; \
409     })
410 #define imcheck_composite(src, dst, pat, src_rect, dst_rect, pat_rect, ...) \
411     ( { \
412         IM_STATUS ret = IM_STATUS_NOERROR; \
413         int args[] = {__VA_ARGS__}; \
414         int argc = sizeof(args)/sizeof(int); \
415         if (argc == 0) { \
416             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \
417         } else if (argc == 1) { \
418             ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, args[0]); \
419         } else { \
420             ret = IM_STATUS_FAILED; \
421             printf("check failed\n"); \
422         } \
423         ret; \
424     })
425 IM_API IM_STATUS imcheck_t(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat,
426                            const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect,
427                            const int mdoe_usage);
428 
429 /*
430  * Resize
431  *
432  * @param src
433  * @param dst
434  * @param fx
435  * @param fy
436  * @param interpolation
437  * @param sync
438  *      wait until operation complete
439  *
440  * @returns success or else negative error code.
441  */
442 #define imresize(src, dst, ...) \
443     ( { \
444         IM_STATUS ret = IM_STATUS_SUCCESS; \
445         double args[] = {__VA_ARGS__}; \
446         int argc = sizeof(args)/sizeof(double); \
447         if (argc == 0) { \
448             ret = imresize_t(src, dst, 0, 0, INTER_LINEAR, 1); \
449         } else if (argc == 2) { \
450             ret = imresize_t(src, dst, args[0], args[1], INTER_LINEAR, 1); \
451         } else if (argc == 3) { \
452             ret = imresize_t(src, dst, args[0], args[1], (int)args[2], 1); \
453         } else if (argc == 4) { \
454             ret = imresize_t(src, dst, args[0], args[1], (int)args[2], (int)args[3]); \
455         } else { \
456             ret = IM_STATUS_INVALID_PARAM; \
457             printf("invalid parameter\n"); \
458         } \
459         ret; \
460     })
461 
462 #define impyramid(src, dst, direction) \
463         imresize_t(src, \
464                    dst, \
465                    (direction) == IM_UP_SCALE ? 0.5 : 2, \
466                    (direction) == IM_UP_SCALE ? 0.5 : 2, \
467                    INTER_LINEAR, 1)
468 
469 IM_API IM_STATUS imresize_t(const rga_buffer_t src, rga_buffer_t dst, double fx,
470                             double fy, int interpolation, int sync);
471 
472 /*
473  * Crop
474  *
475  * @param src
476  * @param dst
477  * @param rect
478  * @param sync
479  *      wait until operation complete
480  *
481  * @returns success or else negative error code.
482  */
483 #define imcrop(src, dst, rect, ...) \
484     ( { \
485         IM_STATUS ret = IM_STATUS_SUCCESS; \
486         int args[] = {__VA_ARGS__}; \
487         int argc = sizeof(args)/sizeof(int); \
488         if (argc == 0) { \
489             ret = imcrop_t(src, dst, rect, 1); \
490         } else if (argc == 1) { \
491             ret = imcrop_t(src, dst, rect, args[0]);; \
492         } else { \
493             ret = IM_STATUS_INVALID_PARAM; \
494             printf("invalid parameter\n"); \
495         } \
496         ret; \
497     })
498 
499 IM_API IM_STATUS imcrop_t(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync);
500 
501 /*
502  * rotation
503  *
504  * @param src
505  * @param dst
506  * @param rotation
507  *      IM_HAL_TRANSFORM_ROT_90
508  *      IM_HAL_TRANSFORM_ROT_180
509  *      IM_HAL_TRANSFORM_ROT_270
510  * @param sync
511  *      wait until operation complete
512  *
513  * @returns success or else negative error code.
514  */
515 #define imrotate(src, dst, rotation, ...) \
516     ( { \
517         IM_STATUS ret = IM_STATUS_SUCCESS; \
518         int args[] = {__VA_ARGS__}; \
519         int argc = sizeof(args)/sizeof(int); \
520         if (argc == 0) { \
521             ret = imrotate_t(src, dst, rotation, 1); \
522         } else if (argc == 1) { \
523             ret = imrotate_t(src, dst, rotation, args[0]);; \
524         } else { \
525             ret = IM_STATUS_INVALID_PARAM; \
526             printf("invalid parameter\n"); \
527         } \
528         ret; \
529     })
530 
531 IM_API IM_STATUS imrotate_t(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync);
532 
533 /*
534  * flip
535  *
536  * @param src
537  * @param dst
538  * @param mode
539  *      IM_HAL_TRANSFORM_FLIP_H
540  *      IM_HAL_TRANSFORM_FLIP_V
541  * @param sync
542  *      wait until operation complete
543  *
544  * @returns success or else negative error code.
545  */
546 #define imflip(src, dst, mode, ...) \
547     ( { \
548         IM_STATUS ret = IM_STATUS_SUCCESS; \
549         int args[] = {__VA_ARGS__}; \
550         int argc = sizeof(args)/sizeof(int); \
551         if (argc == 0) { \
552             ret = imflip_t(src, dst, mode, 1); \
553         } else if (argc == 1) { \
554             ret = imflip_t(src, dst, mode, args[0]);; \
555         } else { \
556             ret = IM_STATUS_INVALID_PARAM; \
557             printf("invalid parameter\n"); \
558         } \
559         ret; \
560     })
561 
562 IM_API IM_STATUS imflip_t (const rga_buffer_t src, rga_buffer_t dst, int mode, int sync);
563 
564 /*
565  * fill/reset/draw
566  *
567  * @param src
568  * @param dst
569  * @param rect
570  * @param color
571  * @param sync
572  *      wait until operation complete
573  *
574  * @returns success or else negative error code.
575  */
576 #define imfill(buf, rect, color, ...) \
577     ( { \
578         IM_STATUS ret = IM_STATUS_SUCCESS; \
579         int args[] = {__VA_ARGS__}; \
580         int argc = sizeof(args)/sizeof(int); \
581         if (argc == 0) { \
582             ret = imfill_t(buf, rect, color, 1); \
583         } else if (argc == 1) { \
584             ret = imfill_t(buf, rect, color, args[0]);; \
585         } else { \
586             ret = IM_STATUS_INVALID_PARAM; \
587             printf("invalid parameter\n"); \
588         } \
589         ret; \
590     })
591 
592 #define imreset(buf, rect, color, ...) \
593     ( { \
594         IM_STATUS ret = IM_STATUS_SUCCESS; \
595         int args[] = {__VA_ARGS__}; \
596         int argc = sizeof(args)/sizeof(int); \
597         if (argc == 0) { \
598             ret = imfill_t(buf, rect, color, 1); \
599         } else if (argc == 1) { \
600             ret = imfill_t(buf, rect, color, args[0]);; \
601         } else { \
602             ret = IM_STATUS_INVALID_PARAM; \
603             printf("invalid parameter\n"); \
604         } \
605         ret; \
606     })
607 
608 #define imdraw(buf, rect, color, ...) \
609     ( { \
610         IM_STATUS ret = IM_STATUS_SUCCESS; \
611         int args[] = {__VA_ARGS__}; \
612         int argc = sizeof(args)/sizeof(int); \
613         if (argc == 0) { \
614             ret = imfill_t(buf, rect, color, 1); \
615         } else if (argc == 1) { \
616             ret = imfill_t(buf, rect, color, args[0]);; \
617         } else { \
618             ret = IM_STATUS_INVALID_PARAM; \
619             printf("invalid parameter\n"); \
620         } \
621         ret; \
622     })
623 IM_API IM_STATUS imfill_t(rga_buffer_t dst, im_rect rect, int color, int sync);
624 
625 /*
626  * palette
627  *
628  * @param src
629  * @param dst
630  * @param lut
631  * @param sync
632  *      wait until operation complete
633  *
634  * @returns success or else negative error code.
635  */
636 #define impalette(src, dst, lut,  ...) \
637     ( { \
638         IM_STATUS ret = IM_STATUS_SUCCESS; \
639         int args[] = {__VA_ARGS__}; \
640         int argc = sizeof(args)/sizeof(int); \
641         if (argc == 0) { \
642             ret = impalette_t(src, dst, lut, 1); \
643         } else if (argc == 1) { \
644             ret = impalette_t(src, dst, lut, args[0]);; \
645         } else { \
646             ret = IM_STATUS_INVALID_PARAM; \
647             printf("invalid parameter\n"); \
648         } \
649         ret; \
650     })
651 IM_API IM_STATUS impalette_t(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync);
652 
653 /*
654  * translate
655  *
656  * @param src
657  * @param dst
658  * @param x
659  * @param y
660  * @param sync
661  *      wait until operation complete
662  *
663  * @returns success or else negative error code.
664  */
665 #define imtranslate(src, dst, x, y, ...) \
666     ( { \
667         IM_STATUS ret = IM_STATUS_SUCCESS; \
668         int args[] = {__VA_ARGS__}; \
669         int argc = sizeof(args)/sizeof(int); \
670         if (argc == 0) { \
671             ret = imtranslate_t(src, dst, x, y, 1); \
672         } else if (argc == 1) { \
673             ret = imtranslate_t(src, dst, x, y, args[0]);; \
674         } else { \
675             ret = IM_STATUS_INVALID_PARAM; \
676             printf("invalid parameter\n"); \
677         } \
678         ret; \
679     })
680 IM_API IM_STATUS imtranslate_t(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync);
681 
682 /*
683  * copy
684  *
685  * @param src
686  * @param dst
687  * @param sync
688  *      wait until operation complete
689  *
690  * @returns success or else negative error code.
691  */
692 #define imcopy(src, dst, ...) \
693     ( { \
694         IM_STATUS ret = IM_STATUS_SUCCESS; \
695         int args[] = {__VA_ARGS__}; \
696         int argc = sizeof(args)/sizeof(int); \
697         if (argc == 0) { \
698             ret = imcopy_t(src, dst, 1); \
699         } else if (argc == 1) { \
700             ret = imcopy_t(src, dst, args[0]);; \
701         } else { \
702             ret = IM_STATUS_INVALID_PARAM; \
703             printf("invalid parameter\n"); \
704         } \
705         ret; \
706     })
707 
708 IM_API IM_STATUS imcopy_t(const rga_buffer_t src, rga_buffer_t dst, int sync);
709 
710 /*
711  * blend (SRC + DST -> DST or SRCA + SRCB -> DST)
712  *
713  * @param srcA
714  * @param srcB can be NULL.
715  * @param dst
716  * @param mode
717  *      IM_ALPHA_BLEND_MODE
718  * @param sync
719  *      wait until operation complete
720  *
721  * @returns success or else negative error code.
722  */
723 #define imblend(srcA, dst, ...) \
724     ( { \
725         IM_STATUS ret = IM_STATUS_SUCCESS; \
726         rga_buffer_t srcB; \
727         errno_t eok = memset_s(&srcB, sizeof(rga_buffer_t), 0x00, sizeof(rga_buffer_t)); \
728         if (!eok) { \
729             printf("memset_s failed!\n"); \
730         } \
731         int args[] = {__VA_ARGS__}; \
732         int argc = sizeof(args)/sizeof(int); \
733         if (argc == 0) { \
734             ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
735         } else if (argc == 1) { \
736             ret = imblend_t(srcA, srcB, dst, args[0], 1); \
737         } else if (argc == 2) { \
738             ret = imblend_t(srcA, srcB, dst, args[0], args[1]); \
739         } else { \
740             ret = IM_STATUS_INVALID_PARAM; \
741             printf("invalid parameter\n"); \
742         } \
743         ret; \
744     })
745 #define imcomposite(srcA, srcB, dst, ...) \
746     ( { \
747         IM_STATUS ret = IM_STATUS_SUCCESS; \
748         int args[] = {__VA_ARGS__}; \
749         int argc = sizeof(args)/sizeof(int); \
750         if (argc == 0) { \
751             ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
752         } else if (argc == 1) { \
753             ret = imblend_t(srcA, srcB, dst, args[0], 1); \
754         } else if (argc == 2) { \
755             ret = imblend_t(srcA, srcB, dst, args[0], args[1]); \
756         } else { \
757             ret = IM_STATUS_INVALID_PARAM; \
758             printf("invalid parameter\n"); \
759         } \
760         ret; \
761     })
762 IM_API IM_STATUS imblend_t(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode, int sync);
763 
764 /*
765  * color key
766  *
767  * @param src
768  * @param dst
769  * @param colorkey_range
770  *      max color
771  *      min color
772  * @param sync
773  *      wait until operation complete
774  *
775  * @returns success or else negative error code.
776  */
777 #define imcolorkey(src, dst, range, ...) \
778     ( { \
779         IM_STATUS ret = IM_STATUS_SUCCESS; \
780         int args[] = {__VA_ARGS__}; \
781         int argc = sizeof(args)/sizeof(int); \
782         if (argc == 0) { \
783             ret = imcolorkey_t(src, dst, range, IM_ALPHA_COLORKEY_NORMAL, 1); \
784         } else if (argc == 1) { \
785             ret = imcolorkey_t(src, dst, range, args[0], 1); \
786         } else if (argc == 2) { \
787             ret = imcolorkey_t(src, dst, range, args[0], args[1]); \
788         } else { \
789             ret = IM_STATUS_INVALID_PARAM; \
790             printf("invalid parameter\n"); \
791         } \
792         ret; \
793     })
794 IM_API IM_STATUS imcolorkey_t(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode, int sync);
795 
796 /*
797  * format convert
798  *
799  * @param src
800  * @param dst
801  * @param sfmt
802  * @param dfmt
803  * @param mode
804  *      color space mode: IM_COLOR_SPACE_MODE
805  * @param sync
806  *      wait until operation complete
807  *
808  * @returns success or else negative error code.
809  */
810 #define imcvtcolor(src, dst, sfmt, dfmt, ...) \
811     ( { \
812         IM_STATUS ret = IM_STATUS_SUCCESS; \
813         int args[] = {__VA_ARGS__}; \
814         int argc = sizeof(args)/sizeof(int); \
815         if (argc == 0) { \
816             ret = imcvtcolor_t(src, dst, sfmt, dfmt, IM_COLOR_SPACE_DEFAULT, 1); \
817         } else if (argc == 1) { \
818             ret = imcvtcolor_t(src, dst, sfmt, dfmt, args[0], 1); \
819         } else if (argc == 2) { \
820             ret = imcvtcolor_t(src, dst, sfmt, dfmt, args[0], args[1]); \
821         } else { \
822             ret = IM_STATUS_INVALID_PARAM; \
823             printf("invalid parameter\n"); \
824         } \
825         ret; \
826     })
827 
828 IM_API IM_STATUS imcvtcolor_t(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode, int sync);
829 
830 /*
831  * nn quantize
832  *
833  * @param src
834  * @param dst
835  * @param nninfo
836  * @param sync
837  *      wait until operation complete
838  *
839  * @returns success or else negative error code.
840  */
841 #define imquantize(src, dst, nn_info, ...) \
842     ( { \
843         IM_STATUS ret = IM_STATUS_SUCCESS; \
844         int args[] = {__VA_ARGS__}; \
845         int argc = sizeof(args)/sizeof(int); \
846         if (argc == 0) { \
847             ret = imquantize_t(src, dst, nn_info, 1); \
848         } else if (argc == 1) { \
849             ret = imquantize_t(src, dst, nn_info, args[0]);; \
850         } else { \
851             ret = IM_STATUS_INVALID_PARAM; \
852             printf("invalid parameter\n"); \
853         } \
854         ret; \
855     })
856 
857 IM_API IM_STATUS imquantize_t(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync);
858 
859 /*
860  * ROP
861  *
862  * @param src
863  * @param dst
864  * @param rop_code
865  * @param sync
866  *      wait until operation complete
867  *
868  * @returns success or else negative error code.
869  */
870 #define imrop(src, dst, rop_code, ...) \
871     ( { \
872         IM_STATUS ret = IM_STATUS_SUCCESS; \
873         int args[] = {__VA_ARGS__}; \
874         int argc = sizeof(args)/sizeof(int); \
875         if (argc == 0) { \
876             ret = imrop_t(src, dst, rop_code, 1); \
877         } else if (argc == 1) { \
878             ret = imrop_t(src, dst, rop_code, args[0]);; \
879         } else { \
880             ret = IM_STATUS_INVALID_PARAM; \
881             printf("invalid parameter\n"); \
882         } \
883         ret; \
884     })
885 IM_API IM_STATUS imrop_t(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync);
886 
887 /*
888  * process
889  *
890  * @param src
891  * @param dst
892  * @param usage
893  * @param ...
894  *      wait until operation complete
895  *
896  * @returns success or else negative error code.
897  */
898 IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
899                            im_rect srect, im_rect drect, im_rect prect, int usage);
900 
901 /*
902  * block until all execution is complete
903  *
904  * @returns success or else negative error code.
905  */
906 IM_API IM_STATUS imsync(void);
907 
908 #ifdef __cplusplus
909 }
910 #endif
911 #endif /* _im2d_h_ */
912