xref: /OK3568_Linux_fs/external/rknpu2/examples/rknn_yolov5_demo/utils/drawing.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include "drawing.h"
2 #include "string.h"
3 
4 #define max(a, b) (((a) > (b)) ? (a) : (b))
5 #define min(a, b) (((a) < (b)) ? (a) : (b))
6 
draw_rectangle_c1(unsigned char * pixels,int w,int h,int stride,int rx,int ry,int rw,int rh,unsigned int color,int thickness)7 void draw_rectangle_c1(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness)
8 {
9     const unsigned char* pen_color = (const unsigned char*)&color;
10 
11     if (thickness == -1)
12     {
13         // filled
14         for (int y = ry; y < ry + rh; y++)
15         {
16             if (y < 0)
17                 continue;
18 
19             if (y >= h)
20                 break;
21 
22             unsigned char* p = pixels + stride * y;
23 
24             for (int x = rx; x < rx + rw; x++)
25             {
26                 if (x < 0)
27                     continue;
28 
29                 if (x >= w)
30                     break;
31 
32                 p[x] = pen_color[0];
33             }
34         }
35 
36         return;
37     }
38 
39     const int t0 = thickness / 2;
40     const int t1 = thickness - t0;
41 
42     // draw top
43     {
44         for (int y = ry - t0; y < ry + t1; y++)
45         {
46             if (y < 0)
47                 continue;
48 
49             if (y >= h)
50                 break;
51 
52             unsigned char* p = pixels + stride * y;
53 
54             for (int x = rx - t0; x < rx + rw + t1; x++)
55             {
56                 if (x < 0)
57                     continue;
58 
59                 if (x >= w)
60                     break;
61 
62                 p[x] = pen_color[0];
63             }
64         }
65     }
66 
67     // draw bottom
68     {
69         for (int y = ry + rh - t0; y < ry + rh + t1; y++)
70         {
71             if (y < 0)
72                 continue;
73 
74             if (y >= h)
75                 break;
76 
77             unsigned char* p = pixels + stride * y;
78 
79             for (int x = rx - t0; x < rx + rw + t1; x++)
80             {
81                 if (x < 0)
82                     continue;
83 
84                 if (x >= w)
85                     break;
86 
87                 p[x] = pen_color[0];
88             }
89         }
90     }
91 
92     // draw left
93     for (int x = rx - t0; x < rx + t1; x++)
94     {
95         if (x < 0)
96             continue;
97 
98         if (x >= w)
99             break;
100 
101         for (int y = ry + t1; y < ry + rh - t0; y++)
102         {
103             if (y < 0)
104                 continue;
105 
106             if (y >= h)
107                 break;
108 
109             unsigned char* p = pixels + stride * y;
110 
111             p[x] = pen_color[0];
112         }
113     }
114 
115     // draw right
116     for (int x = rx + rw - t0; x < rx + rw + t1; x++)
117     {
118         if (x < 0)
119             continue;
120 
121         if (x >= w)
122             break;
123 
124         for (int y = ry + t1; y < ry + rh - t0; y++)
125         {
126             if (y < 0)
127                 continue;
128 
129             if (y >= h)
130                 break;
131 
132             unsigned char* p = pixels + stride * y;
133 
134             p[x] = pen_color[0];
135         }
136     }
137 }
138 
draw_rectangle_c2(unsigned char * pixels,int w,int h,int stride,int rx,int ry,int rw,int rh,unsigned int color,int thickness)139 void draw_rectangle_c2(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness)
140 {
141     const unsigned char* pen_color = (const unsigned char*)&color;
142 
143     if (thickness == -1)
144     {
145         // filled
146         for (int y = ry; y < ry + rh; y++)
147         {
148             if (y < 0)
149                 continue;
150 
151             if (y >= h)
152                 break;
153 
154             unsigned char* p = pixels + stride * y;
155 
156             for (int x = rx; x < rx + rw; x++)
157             {
158                 if (x < 0)
159                     continue;
160 
161                 if (x >= w)
162                     break;
163 
164                 p[x * 2 + 0] = pen_color[0];
165                 p[x * 2 + 1] = pen_color[1];
166             }
167         }
168 
169         return;
170     }
171 
172     const int t0 = thickness / 2;
173     const int t1 = thickness - t0;
174 
175     // draw top
176     {
177         for (int y = ry - t0; y < ry + t1; y++)
178         {
179             if (y < 0)
180                 continue;
181 
182             if (y >= h)
183                 break;
184 
185             unsigned char* p = pixels + stride * y;
186 
187             for (int x = rx - t0; x < rx + rw + t1; x++)
188             {
189                 if (x < 0)
190                     continue;
191 
192                 if (x >= w)
193                     break;
194 
195                 p[x * 2 + 0] = pen_color[0];
196                 p[x * 2 + 1] = pen_color[1];
197             }
198         }
199     }
200 
201     // draw bottom
202     {
203         for (int y = ry + rh - t0; y < ry + rh + t1; y++)
204         {
205             if (y < 0)
206                 continue;
207 
208             if (y >= h)
209                 break;
210 
211             unsigned char* p = pixels + stride * y;
212 
213             for (int x = rx - t0; x < rx + rw + t1; x++)
214             {
215                 if (x < 0)
216                     continue;
217 
218                 if (x >= w)
219                     break;
220 
221                 p[x * 2 + 0] = pen_color[0];
222                 p[x * 2 + 1] = pen_color[1];
223             }
224         }
225     }
226 
227     // draw left
228     for (int x = rx - t0; x < rx + t1; x++)
229     {
230         if (x < 0)
231             continue;
232 
233         if (x >= w)
234             break;
235 
236         for (int y = ry + t1; y < ry + rh - t0; y++)
237         {
238             if (y < 0)
239                 continue;
240 
241             if (y >= h)
242                 break;
243 
244             unsigned char* p = pixels + stride * y;
245 
246             p[x * 2 + 0] = pen_color[0];
247             p[x * 2 + 1] = pen_color[1];
248         }
249     }
250 
251     // draw right
252     for (int x = rx + rw - t0; x < rx + rw + t1; x++)
253     {
254         if (x < 0)
255             continue;
256 
257         if (x >= w)
258             break;
259 
260         for (int y = ry + t1; y < ry + rh - t0; y++)
261         {
262             if (y < 0)
263                 continue;
264 
265             if (y >= h)
266                 break;
267 
268             unsigned char* p = pixels + stride * y;
269 
270             p[x * 2 + 0] = pen_color[0];
271             p[x * 2 + 1] = pen_color[1];
272         }
273     }
274 }
275 
draw_rectangle_c3(unsigned char * pixels,int w,int h,int stride,int rx,int ry,int rw,int rh,unsigned int color,int thickness)276 void draw_rectangle_c3(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness)
277 {
278     const unsigned char* pen_color = (const unsigned char*)&color;
279 
280     if (thickness == -1)
281     {
282         // filled
283         for (int y = ry; y < ry + rh; y++)
284         {
285             if (y < 0)
286                 continue;
287 
288             if (y >= h)
289                 break;
290 
291             unsigned char* p = pixels + stride * y;
292 
293             for (int x = rx; x < rx + rw; x++)
294             {
295                 if (x < 0)
296                     continue;
297 
298                 if (x >= w)
299                     break;
300 
301                 p[x * 3 + 0] = pen_color[0];
302                 p[x * 3 + 1] = pen_color[1];
303                 p[x * 3 + 2] = pen_color[2];
304             }
305         }
306 
307         return;
308     }
309 
310     const int t0 = thickness / 2;
311     const int t1 = thickness - t0;
312 
313     // draw top
314     {
315         for (int y = ry - t0; y < ry + t1; y++)
316         {
317             if (y < 0)
318                 continue;
319 
320             if (y >= h)
321                 break;
322 
323             unsigned char* p = pixels + stride * y;
324 
325             for (int x = rx - t0; x < rx + rw + t1; x++)
326             {
327                 if (x < 0)
328                     continue;
329 
330                 if (x >= w)
331                     break;
332 
333                 p[x * 3 + 0] = pen_color[0];
334                 p[x * 3 + 1] = pen_color[1];
335                 p[x * 3 + 2] = pen_color[2];
336             }
337         }
338     }
339 
340     // draw bottom
341     {
342         for (int y = ry + rh - t0; y < ry + rh + t1; y++)
343         {
344             if (y < 0)
345                 continue;
346 
347             if (y >= h)
348                 break;
349 
350             unsigned char* p = pixels + stride * y;
351 
352             for (int x = rx - t0; x < rx + rw + t1; x++)
353             {
354                 if (x < 0)
355                     continue;
356 
357                 if (x >= w)
358                     break;
359 
360                 p[x * 3 + 0] = pen_color[0];
361                 p[x * 3 + 1] = pen_color[1];
362                 p[x * 3 + 2] = pen_color[2];
363             }
364         }
365     }
366 
367     // draw left
368     for (int x = rx - t0; x < rx + t1; x++)
369     {
370         if (x < 0)
371             continue;
372 
373         if (x >= w)
374             break;
375 
376         for (int y = ry + t1; y < ry + rh - t0; y++)
377         {
378             if (y < 0)
379                 continue;
380 
381             if (y >= h)
382                 break;
383 
384             unsigned char* p = pixels + stride * y;
385 
386             p[x * 3 + 0] = pen_color[0];
387             p[x * 3 + 1] = pen_color[1];
388             p[x * 3 + 2] = pen_color[2];
389         }
390     }
391 
392     // draw right
393     for (int x = rx + rw - t0; x < rx + rw + t1; x++)
394     {
395         if (x < 0)
396             continue;
397 
398         if (x >= w)
399             break;
400 
401         for (int y = ry + t1; y < ry + rh - t0; y++)
402         {
403             if (y < 0)
404                 continue;
405 
406             if (y >= h)
407                 break;
408 
409             unsigned char* p = pixels + stride * y;
410 
411             p[x * 3 + 0] = pen_color[0];
412             p[x * 3 + 1] = pen_color[1];
413             p[x * 3 + 2] = pen_color[2];
414         }
415     }
416 }
417 
draw_rectangle_c4(unsigned char * pixels,int w,int h,int stride,int rx,int ry,int rw,int rh,unsigned int color,int thickness)418 void draw_rectangle_c4(unsigned char* pixels, int w, int h, int stride, int rx, int ry, int rw, int rh, unsigned int color, int thickness)
419 {
420     const unsigned char* pen_color = (const unsigned char*)&color;
421 
422     if (thickness == -1)
423     {
424         // filled
425         for (int y = ry; y < ry + rh; y++)
426         {
427             if (y < 0)
428                 continue;
429 
430             if (y >= h)
431                 break;
432 
433             unsigned char* p = pixels + stride * y;
434 
435             for (int x = rx; x < rx + rw; x++)
436             {
437                 if (x < 0)
438                     continue;
439 
440                 if (x >= w)
441                     break;
442 
443                 p[x * 4 + 0] = pen_color[0];
444                 p[x * 4 + 1] = pen_color[1];
445                 p[x * 4 + 2] = pen_color[2];
446                 p[x * 4 + 3] = pen_color[3];
447             }
448         }
449 
450         return;
451     }
452 
453     const int t0 = thickness / 2;
454     const int t1 = thickness - t0;
455 
456     // draw top
457     {
458         for (int y = ry - t0; y < ry + t1; y++)
459         {
460             if (y < 0)
461                 continue;
462 
463             if (y >= h)
464                 break;
465 
466             unsigned char* p = pixels + stride * y;
467 
468             for (int x = rx - t0; x < rx + rw + t1; x++)
469             {
470                 if (x < 0)
471                     continue;
472 
473                 if (x >= w)
474                     break;
475 
476                 p[x * 4 + 0] = pen_color[0];
477                 p[x * 4 + 1] = pen_color[1];
478                 p[x * 4 + 2] = pen_color[2];
479                 p[x * 4 + 3] = pen_color[3];
480             }
481         }
482     }
483 
484     // draw bottom
485     {
486         for (int y = ry + rh - t0; y < ry + rh + t1; y++)
487         {
488             if (y < 0)
489                 continue;
490 
491             if (y >= h)
492                 break;
493 
494             unsigned char* p = pixels + stride * y;
495 
496             for (int x = rx - t0; x < rx + rw + t1; x++)
497             {
498                 if (x < 0)
499                     continue;
500 
501                 if (x >= w)
502                     break;
503 
504                 p[x * 4 + 0] = pen_color[0];
505                 p[x * 4 + 1] = pen_color[1];
506                 p[x * 4 + 2] = pen_color[2];
507                 p[x * 4 + 3] = pen_color[3];
508             }
509         }
510     }
511 
512     // draw left
513     for (int x = rx - t0; x < rx + t1; x++)
514     {
515         if (x < 0)
516             continue;
517 
518         if (x >= w)
519             break;
520 
521         for (int y = ry + t1; y < ry + rh - t0; y++)
522         {
523             if (y < 0)
524                 continue;
525 
526             if (y >= h)
527                 break;
528 
529             unsigned char* p = pixels + stride * y;
530 
531             p[x * 4 + 0] = pen_color[0];
532             p[x * 4 + 1] = pen_color[1];
533             p[x * 4 + 2] = pen_color[2];
534             p[x * 4 + 3] = pen_color[3];
535         }
536     }
537 
538     // draw right
539     for (int x = rx + rw - t0; x < rx + rw + t1; x++)
540     {
541         if (x < 0)
542             continue;
543 
544         if (x >= w)
545             break;
546 
547         for (int y = ry + t1; y < ry + rh - t0; y++)
548         {
549             if (y < 0)
550                 continue;
551 
552             if (y >= h)
553                 break;
554 
555             unsigned char* p = pixels + stride * y;
556 
557             p[x * 4 + 0] = pen_color[0];
558             p[x * 4 + 1] = pen_color[1];
559             p[x * 4 + 2] = pen_color[2];
560             p[x * 4 + 3] = pen_color[3];
561         }
562     }
563 }
564 
draw_rectangle_yuv420sp(unsigned char * yuv420sp,int w,int h,int rx,int ry,int rw,int rh,unsigned int color,int thickness)565 void draw_rectangle_yuv420sp(unsigned char* yuv420sp, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness)
566 {
567     // assert w % 2 == 0
568     // assert h % 2 == 0
569     // assert rx % 2 == 0
570     // assert ry % 2 == 0
571     // assert rw % 2 == 0
572     // assert rh % 2 == 0
573     // assert thickness % 2 == 0
574 
575     const unsigned char* pen_color = (const unsigned char*)&color;
576 
577     unsigned int v_y;
578     unsigned int v_uv;
579     unsigned char* pen_color_y = (unsigned char*)&v_y;
580     unsigned char* pen_color_uv = (unsigned char*)&v_uv;
581     pen_color_y[0] = pen_color[0];
582     pen_color_uv[0] = pen_color[1];
583     pen_color_uv[1] = pen_color[2];
584 
585     unsigned char* Y = yuv420sp;
586     draw_rectangle_c1(Y, w, h, w, rx, ry, rw, rh, v_y, thickness);
587 
588     unsigned char* UV = yuv420sp + w * h;
589     int thickness_uv = thickness == -1 ? thickness : max(thickness / 2, 1);
590     draw_rectangle_c2(UV, w / 2, h / 2, w, rx / 2, ry / 2, rw / 2, rh / 2, v_uv, thickness_uv);
591 }
592 
593 
draw_image_yuv420sp(unsigned char * yuv420sp,int w,int h,unsigned char * draw_img,int rx,int ry,int rw,int rh)594 void draw_image_yuv420sp(unsigned char* yuv420sp, int w, int h, unsigned char* draw_img, int rx, int ry, int rw, int rh) {
595     for (int i = 0; i < rh; i++) {
596         memcpy(yuv420sp + (ry+i) * w + rx,  draw_img + i * rw,  rw);
597     }
598     for (int i = 0; i < rh/2; i++) {
599         memcpy(yuv420sp + w*h + (ry/2+i) * w+ rx, draw_img + rw*rh + i*rw, rw);
600     }
601 }