24 #include <fvutils/draw/drawer.h>
25 #include <fvutils/color/yuv.h>
31 namespace firevision {
47 __color = YUV_t::white();
62 Drawer::set_buffer(
unsigned char *buffer,
63 unsigned int width,
unsigned int height)
65 this->__buffer = buffer;
66 this->__width = width;
67 this->__height = height;
77 Drawer::set_color(
unsigned char y,
unsigned char u,
unsigned char v)
102 Drawer::draw_circle(
int center_x,
int center_y,
unsigned int radius)
105 if (__buffer == NULL)
return;
109 r2 = radius * radius;
111 unsigned char *up = YUV422_PLANAR_U_PLANE(__buffer, __width, __height);
112 unsigned char *vp = YUV422_PLANAR_V_PLANE(__buffer, __width, __height);
114 unsigned int x_tmp, y_tmp, ind_tmp;
118 x_tmp = center_x + x;
119 y_tmp = center_y + y;
120 if ( (x_tmp < __width) && (y_tmp < __height) ) {
121 ind_tmp = y_tmp * __width + x_tmp;
122 __buffer[ind_tmp] = __color.Y;
124 up[ind_tmp] = __color.U;
125 vp[ind_tmp] = __color.V;
128 x_tmp = center_x - x;
129 y_tmp = center_y + y;
130 if ( (x_tmp < __width) && (y_tmp < __height) ) {
131 ind_tmp = y_tmp * __width + x_tmp;
132 __buffer[ind_tmp] = __color.Y;
134 up[ind_tmp] = __color.U;
135 vp[ind_tmp] = __color.V;
138 x_tmp = center_x + y;
139 y_tmp = center_y + x;
140 if ( (x_tmp < __width) && (y_tmp < __height) ) {
141 ind_tmp = y_tmp * __width + x_tmp;
142 __buffer[ind_tmp] = __color.Y;
144 up[ind_tmp] = __color.U;
145 vp[ind_tmp] = __color.V;
148 x_tmp = center_x - y;
149 y_tmp = center_y + x;
150 if ( (x_tmp < __width) && (y_tmp < __height) ) {
151 ind_tmp = y_tmp * __width + x_tmp;
152 __buffer[ind_tmp] = __color.Y;
154 up[ind_tmp] = __color.U;
155 vp[ind_tmp] = __color.V;
158 x_tmp = center_x + x;
159 y_tmp = center_y - y;
160 if ( (x_tmp < __width) && (y_tmp < __height) ) {
161 ind_tmp = y_tmp * __width + x_tmp;
162 __buffer[ind_tmp] = __color.Y;
164 up[ind_tmp] = __color.U;
165 vp[ind_tmp] = __color.V;
168 x_tmp = center_x - x;
169 y_tmp = center_y - y;
170 if ( (x_tmp < __width) && (y_tmp < __height)) {
171 ind_tmp = y_tmp * __width + x_tmp;
172 __buffer[ind_tmp] = __color.Y;
174 up[ind_tmp] = __color.U;
175 vp[ind_tmp] = __color.V;
178 x_tmp = center_x + y;
179 y_tmp = center_y - x;
180 if ( (x_tmp < __width) && (y_tmp < __height)) {
181 ind_tmp = y_tmp * __width + x_tmp;
182 __buffer[ind_tmp] = __color.Y;
184 up[ind_tmp] = __color.U;
185 vp[ind_tmp] = __color.V;
188 x_tmp = center_x - y;
189 y_tmp = center_y - x;
190 if ( (x_tmp < __width) && (y_tmp < __height) ) {
191 ind_tmp = y_tmp * __width + x_tmp;
192 __buffer[ind_tmp] = __color.Y;
194 up[ind_tmp] = __color.U;
195 vp[ind_tmp] = __color.V;
199 y=(int)(sqrt((
float)(r2 - x * x))+0.5);
212 Drawer::draw_rectangle(
unsigned int x,
unsigned int y,
213 unsigned int w,
unsigned int h)
216 unsigned char *up = YUV422_PLANAR_U_PLANE(__buffer, __width, __height);
217 unsigned char *vp = YUV422_PLANAR_V_PLANE(__buffer, __width, __height);
220 for (
unsigned int i = x; i < x + w; ++i) {
222 __buffer[ y * __width + i ] = __color.Y;
223 up[ (y * __width + i) / 2 ] = __color.U;
224 vp[ (y * __width + i) / 2 ] = __color.V;
231 for (
unsigned int i = y; i < y + h; ++i) {
233 __buffer[ i * __width + x ] = __color.Y;
234 up[ (i * __width + x) / 2 ] = __color.U;
235 vp[ (i * __width + x) / 2 ] = __color.V;
237 if ( (x + w) < __width ) {
239 __buffer[ i * __width + x + w ] = __color.Y;
240 up[ (i * __width + x + w) / 2 ] = __color.U;
241 vp[ (i * __width + x + w) / 2 ] = __color.V;
246 for (
unsigned int i = x; i < x + w; ++i) {
248 __buffer[ (y + h) * __width + i ] = __color.Y;
249 up[ ((y + h) * __width + i) / 2 ] = __color.U;
250 vp[ ((y + h) * __width + i) / 2 ] = __color.V;
268 Drawer::draw_rectangle_inverted(
unsigned int x,
unsigned int y,
269 unsigned int w,
unsigned int h)
272 unsigned int ind = 0;
275 for (
unsigned int i = x; i < x + w; ++i) {
277 ind = y * __width + i;
278 __buffer[ind] = 255 - __buffer[ind];
285 for (
unsigned int i = y; i < y + h; ++i) {
287 ind = i * __width + x;
288 __buffer[ind] = 255 - __buffer[ind];
290 if ( (x + w) < __width ) {
293 __buffer[ind] = 255 - __buffer[ind];
298 for (
unsigned int i = x; i < x + w; ++i) {
300 __buffer[ind] = 255 - __buffer[ind];
314 Drawer::draw_point(
unsigned int x,
unsigned int y)
316 if ( x > __width)
return;
317 if ( y > __height)
return;
319 unsigned char *up = YUV422_PLANAR_U_PLANE(__buffer, __width, __height);
320 unsigned char *vp = YUV422_PLANAR_V_PLANE(__buffer, __width, __height);
322 __buffer[ y * __width + x ] = __color.Y;
323 up[ (y * __width + x) / 2 ] = __color.U;
324 vp[ (y * __width + x) / 2 ] = __color.V;
336 Drawer::color_point(
unsigned int x,
unsigned int y)
338 if ( x > __width)
return;
339 if ( y > __height)
return;
341 unsigned char *up = YUV422_PLANAR_U_PLANE(__buffer, __width, __height);
342 unsigned char *vp = YUV422_PLANAR_V_PLANE(__buffer, __width, __height);
344 __buffer[ y * __width + x ] = __color.Y;
345 up[ (y * __width + x) / 2 ] = __color.U;
346 vp[ (y * __width + x) / 2 ] = __color.V;
358 Drawer::color_point(
unsigned int x,
unsigned int y,
YUV_t color)
360 if ( x > __width)
return;
361 if ( y > __height)
return;
363 unsigned char *up = YUV422_PLANAR_U_PLANE(__buffer, __width, __height);
364 unsigned char *vp = YUV422_PLANAR_V_PLANE(__buffer, __width, __height);
366 __buffer[ y * __width + x ] = color.
Y;
367 up[ (y * __width + x) / 2 ] = color.
U;
368 vp[ (y * __width + x) / 2 ] = color.
V;
381 Drawer::draw_line(
unsigned int x_start,
unsigned int y_start,
382 unsigned int x_end,
unsigned int y_end)
390 int x, y, dist, xerr, yerr, dx, dy, incx, incy;
391 bool was_inside_image =
false;
393 unsigned char *up = YUV422_PLANAR_U_PLANE(__buffer, __width, __height);
394 unsigned char *vp = YUV422_PLANAR_V_PLANE(__buffer, __width, __height);
397 dx = x_end - x_start;
398 dy = y_end - y_start;
416 dist = (dx > dy) ? dx : dy;
425 for(
int t = 0; t < dist; ++t) {
426 if ( ((
unsigned int)x < __width) && ((
unsigned int)y < __height) ) {
427 if ( (x >= 0) && (y >= 0) ) {
428 was_inside_image =
true;
429 __buffer[ y * __width + x ] = __color.Y;
430 up[ (y * __width + x) / 2 ] = __color.U;
431 vp[ (y * __width + x) / 2 ] = __color.V;
434 if ( was_inside_image ) {
453 if ( (x_end < __width) && (y_end < __height) ) {
454 __buffer[ y_end * __width + x_end ] = __color.Y;
455 up[ (y_end * __width + x_end) / 2 ] = __color.U;
456 vp[ (y_end * __width + x_end) / 2 ] = __color.V;
467 Drawer::draw_cross(
unsigned int x_center,
unsigned int y_center,
unsigned int width)
469 x_center = std::min(x_center, __width);
470 y_center = std::min(y_center, __height);
473 unsigned int a = std::max(0, (
int)x_center - r);
474 unsigned int b = std::min(x_center + r, __width);
475 draw_line(a, y_center, b, y_center);
477 a = std::max(0, (
int)y_center - r);
478 b = std::min(y_center + r, __height);
479 draw_line(x_center, a, x_center, b);