00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <fvutils/draw/mono_drawer.h>
00026 #include <fvutils/color/yuv.h>
00027
00028 #include <cmath>
00029 #include <algorithm>
00030 #include <unistd.h>
00031
00032 #define PUT_POINT( x, y ) \
00033 { \
00034 if( __overlap ) \
00035 __buffer[ y * __width + x ] = std::min(255, __buffer[ y * __width + x ] + __brightness); \
00036 else \
00037 __buffer[ y * __width + x ] = __brightness; \
00038 }
00039
00040 namespace firevision {
00041 #if 0
00042 }
00043 #endif
00044
00045
00046
00047
00048
00049
00050
00051
00052 MonoDrawer::MonoDrawer()
00053 {
00054 __buffer = NULL;
00055 __brightness = 1;
00056 __overlap = 1;
00057 }
00058
00059
00060 MonoDrawer::~MonoDrawer()
00061 {
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 void
00071 MonoDrawer::set_buffer(unsigned char *buffer,
00072 unsigned int width, unsigned int height)
00073 {
00074 this->__buffer = buffer;
00075 this->__width = width;
00076 this->__height = height;
00077 }
00078
00079
00080
00081
00082
00083 void
00084 MonoDrawer::set_brightness(unsigned char b)
00085 {
00086 __brightness = b;
00087 }
00088
00089
00090
00091
00092
00093 void
00094 MonoDrawer::set_overlap(bool o)
00095 {
00096 __overlap = o;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106 void
00107 MonoDrawer::draw_circle(int center_x, int center_y, unsigned int radius)
00108 {
00109 if (__buffer == NULL) return;
00110
00111 unsigned int x = 0,
00112 y = radius,
00113 r2 = radius * radius;
00114
00115 unsigned int x_tmp, y_tmp;
00116
00117 while (x <= y) {
00118
00119 x_tmp = center_x + x;
00120 y_tmp = center_y + y;
00121 if ( (x_tmp < __width) && (y_tmp < __height) )
00122 PUT_POINT( x_tmp, y_tmp );
00123
00124 x_tmp = center_x - x;
00125 y_tmp = center_y + y;
00126 if ( (x_tmp < __width) && (y_tmp < __height) )
00127 PUT_POINT( x_tmp, y_tmp );
00128
00129 x_tmp = center_x + y;
00130 y_tmp = center_y + x;
00131 if ( (x_tmp < __width) && (y_tmp < __height) )
00132 PUT_POINT( x_tmp, y_tmp );
00133
00134 x_tmp = center_x - y;
00135 y_tmp = center_y + x;
00136 if ( (x_tmp < __width) && (y_tmp < __height) )
00137 PUT_POINT( x_tmp, y_tmp );
00138
00139 x_tmp = center_x + x;
00140 y_tmp = center_y - y;
00141 if ( (x_tmp < __width) && (y_tmp < __height) )
00142 PUT_POINT( x_tmp, y_tmp );
00143
00144 x_tmp = center_x - x;
00145 y_tmp = center_y - y;
00146 if ( (x_tmp < __width) && (y_tmp < __height) )
00147 PUT_POINT( x_tmp, y_tmp );
00148
00149 x_tmp = center_x + y;
00150 y_tmp = center_y - x;
00151 if ( (x_tmp < __width) && (y_tmp < __height) )
00152 PUT_POINT( x_tmp, y_tmp );
00153
00154 x_tmp = center_x - y;
00155 y_tmp = center_y - x;
00156 if ( (x_tmp < __width) && (y_tmp < __height) )
00157 PUT_POINT( x_tmp, y_tmp );
00158
00159 ++x;
00160 y=(int)(sqrt((float)(r2 - x * x))+0.5);
00161 }
00162
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172 void
00173 MonoDrawer::draw_rectangle(unsigned int x, unsigned int y,
00174 unsigned int w, unsigned int h)
00175 {
00176
00177
00178 for (unsigned int i = x; i < x + w; ++i) {
00179 if ( i < __width ) {
00180 PUT_POINT( i, y );
00181 } else {
00182 break;
00183 }
00184 }
00185
00186
00187 for (unsigned int i = y; i < y + h; ++i) {
00188
00189 PUT_POINT( x, i );
00190
00191 if ( (x + w) < __width ) {
00192
00193 PUT_POINT( x+w, i );
00194 }
00195 }
00196
00197
00198 for (unsigned int i = x; i < x + w; ++i) {
00199 if ( i < __width ) {
00200 PUT_POINT( i, y+h );
00201 } else {
00202 break;
00203 }
00204 }
00205
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 void
00218 MonoDrawer::draw_rectangle_inverted(unsigned int x, unsigned int y,
00219 unsigned int w, unsigned int h)
00220 {
00221
00222 unsigned int ind = 0;
00223
00224
00225 for (unsigned int i = x; i < x + w; ++i) {
00226 if ( i < __width ) {
00227 ind = y * __width + i;
00228 __buffer[ind] = 255 - __buffer[ind];
00229 } else {
00230 break;
00231 }
00232 }
00233
00234
00235 for (unsigned int i = y; i < y + h; ++i) {
00236
00237 ind = i * __width + x;
00238 __buffer[ind] = 255 - __buffer[ind];
00239
00240 if ( (x + w) < __width ) {
00241
00242 ind += w;
00243 __buffer[ind] = 255 - __buffer[ind];
00244 }
00245 }
00246
00247
00248 for (unsigned int i = x; i < x + w; ++i) {
00249 if ( i < __width ) {
00250 __buffer[ind] = 255 - __buffer[ind];
00251 } else {
00252 break;
00253 }
00254 }
00255
00256 }
00257
00258
00259
00260
00261
00262
00263 void
00264 MonoDrawer::draw_point(unsigned int x, unsigned int y)
00265 {
00266 if ( x > __width) return;
00267 if ( y > __height) return;
00268
00269 PUT_POINT( x, y );
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 void
00282 MonoDrawer::draw_line(unsigned int x_start, unsigned int y_start,
00283 unsigned int x_end, unsigned int y_end)
00284 {
00285
00286
00287
00288
00289
00290
00291 int x, y, dist, xerr, yerr, dx, dy, incx, incy;
00292 bool was_inside_image = false;
00293
00294
00295 dx = x_end - x_start;
00296 dy = y_end - y_start;
00297
00298
00299 if(dx < 0) {
00300 incx = -1;
00301 dx = -dx;
00302 } else {
00303 incx = dx ? 1 : 0;
00304 }
00305
00306 if(dy < 0) {
00307 incy = -1;
00308 dy = -dy;
00309 } else {
00310 incy = dy ? 1 : 0;
00311 }
00312
00313
00314 dist = (dx > dy) ? dx : dy;
00315
00316
00317 x = x_start;
00318 y = y_start;
00319 xerr = dx;
00320 yerr = dy;
00321
00322
00323 for(int t = 0; t < dist; ++t) {
00324 if ( ((unsigned int)x < __width) && ((unsigned int)y < __height) ) {
00325 if ( (x >= 0) && (y >= 0) ) {
00326 was_inside_image = true;
00327 PUT_POINT( x, y );
00328 }
00329 } else {
00330 if ( was_inside_image ) {
00331 break;
00332 }
00333 }
00334
00335 xerr += dx;
00336 yerr += dy;
00337
00338 if(xerr > dist) {
00339 xerr -= dist;
00340 x += incx;
00341 }
00342
00343 if(yerr>dist) {
00344 yerr -= dist;
00345 y += incy;
00346 }
00347 }
00348
00349 if ( (x_end < __width) && (y_end < __height) ) {
00350 PUT_POINT( x_end, y_end );
00351 }
00352
00353 }
00354
00355
00356
00357
00358
00359
00360 void
00361 MonoDrawer::draw_cross(unsigned int x_center, unsigned int y_center, unsigned int width)
00362 {
00363 x_center = std::min(x_center, __width);
00364 y_center = std::min(y_center, __height);
00365
00366 int r = width / 2;
00367 unsigned int a = std::max(0, (int)x_center - r);
00368 unsigned int b = std::min(x_center + r, __width);
00369 draw_line(a, y_center, b, y_center);
00370
00371 a = std::max(0, (int)y_center - r);
00372 b = std::min(y_center + r, __height);
00373 draw_line(x_center, a, x_center, b);
00374 }
00375 }