00001
00002 #include "bgui_image_tableau.h"
00003
00004
00005
00006
00007
00008 #include <vcl_cmath.h>
00009 #include <vcl_cstdio.h>
00010 #include <vgui/vgui_event.h>
00011 #include <vgui/vgui.h>
00012 #include <vgui/vgui_projection_inspector.h>
00013 #include <vil1/vil1_image.h>
00014 #include <vil1/vil1_rgba.h>
00015 #include <vil/vil_image_view.h>
00016 #include <vgui/vgui_range_map_params.h>
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 bgui_image_tableau::bgui_image_tableau()
00027 {
00028 handle_motion_ = true; locked_ = false; show_path_=false;
00029 tt_ = new vgui_text_tableau();
00030 }
00031
00032 bgui_image_tableau::bgui_image_tableau(vil_image_resource_sptr const & img,
00033 vgui_range_map_params_sptr const& rmp)
00034 : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
00035 tt_ = new vgui_text_tableau();}
00036
00037 bgui_image_tableau::bgui_image_tableau(vil_image_view_base const & img,
00038 vgui_range_map_params_sptr const& rmp)
00039 : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
00040 tt_ = new vgui_text_tableau();}
00041
00042 bgui_image_tableau::bgui_image_tableau(vil1_image const & img,
00043 vgui_range_map_params_sptr const& rmp)
00044 : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
00045 tt_ = new vgui_text_tableau();}
00046
00047 bgui_image_tableau::bgui_image_tableau(char const *f,
00048 vgui_range_map_params_sptr const& rmp)
00049 : base(f, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
00050 tt_ = new vgui_text_tableau();}
00051
00052
00053
00054 vil1_image bgui_image_tableau::get_image() const
00055 {
00056 return base::get_image();
00057 }
00058
00059 vil_image_resource_sptr bgui_image_tableau::get_image_resource() const
00060 {
00061 return base::get_image_resource();
00062 }
00063
00064 void bgui_image_tableau::get_pixel_info_from_frame_buffer(const int x, const int y, vgui_event const &e, char* msg)
00065 {
00066
00067
00068 glPixelZoom(1,1);
00069 glPixelTransferi(GL_MAP_COLOR,0);
00070 glPixelTransferi(GL_RED_SCALE,1); glPixelTransferi(GL_RED_BIAS,0);
00071 glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
00072 glPixelTransferi(GL_BLUE_SCALE,1); glPixelTransferi(GL_BLUE_BIAS,0);
00073
00074 glPixelStorei(GL_PACK_ALIGNMENT,1);
00075 glPixelStorei(GL_PACK_ROW_LENGTH,0);
00076 glPixelStorei(GL_PACK_SKIP_PIXELS,0);
00077 glPixelStorei(GL_PACK_SKIP_ROWS,0);
00078 vil1_rgba<GLubyte> pixel;
00079 glReadPixels(e.wx, e.wy,
00080 1, 1,
00081 GL_RGBA,
00082 GL_UNSIGNED_BYTE,
00083 &pixel);
00084 vcl_sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d]", x, y,
00085 pixel.r, pixel.g, pixel.b);
00086 }
00087
00088 void bgui_image_tableau::
00089 get_pixel_info_from_image(const int x, const int y,
00090 vgui_event const &e, char* msg)
00091 {
00092
00093
00094 vil_image_resource_sptr r = this->get_image_resource();
00095 if (!r) {
00096 if (!this->get_image())
00097 {
00098 vcl_sprintf(msg, "(%d, %d) ?", x, y);
00099 return;
00100 }
00101 else
00102 {
00103 this->get_pixel_info_from_frame_buffer(x, y, e, msg);
00104 return;
00105 }
00106 }
00107
00108 unsigned w = r->ni(), h = r->nj(), n_p = r->nplanes();
00109 if (x<0||x>=int(w)||y<0||y>=int(h))
00110 {
00111 vcl_sprintf(msg, "(%d, %d) ?", 0, 0);
00112 return;
00113 }
00114 vil_pixel_format type = r->pixel_format();
00115 switch (type )
00116 {
00117 case VIL_PIXEL_FORMAT_BOOL:
00118 {
00119 vil_image_view<bool> v = r->get_view();
00120 if (!v)
00121 vcl_sprintf(msg, "Pixel Not Available");
00122 else
00123 vcl_sprintf(msg, "(%d, %d) (bool) %d", x, y, v(x,y));
00124 return;
00125 }
00126 case VIL_PIXEL_FORMAT_BYTE:
00127 {
00128 if (n_p==1)
00129 {
00130 vil_image_view<vxl_byte> v = r->get_view(x,1,y,1);
00131 if (!v)
00132 vcl_sprintf(msg, "Pixel Not Available");
00133 else
00134 vcl_sprintf(msg, "(%d, %d) (ubyte) %d", x, y, v(0,0));
00135 return;
00136 }
00137 else if (n_p==3)
00138 {
00139 vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
00140 if (!v)
00141 vcl_sprintf(msg, "Pixel Not Available");
00142 else
00143 vcl_sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d]", x, y,
00144 v(0,0,0), v(0,0,1), v(0,0,2) );
00145 return;
00146 }
00147 else if (n_p==4) {
00148 vcl_sprintf(msg, "(%d, %d) Pixel type not Available", x, y);
00149 return;
00150 }
00151 return;
00152 }
00153 case VIL_PIXEL_FORMAT_SBYTE:
00154 {
00155 if (n_p==1)
00156 {
00157 vil_image_view<vxl_sbyte> v = r->get_view(x,1,y,1);
00158 if (!v)
00159 vcl_sprintf(msg, "Pixel Not Available");
00160 else
00161 vcl_sprintf(msg, "(%d, %d) (sbyte) %d", x, y, v(0,0));
00162 return;
00163 }
00164 else if (n_p==3)
00165 {
00166 vil_image_view<vil_rgb<vxl_sbyte> > v = r->get_view(x,1,y,1);
00167 if (!v)
00168 vcl_sprintf(msg, "Pixel Not Available");
00169 else
00170 vcl_sprintf(msg, "(%d, %d) (sbyte)[ R=%d,G=%d,B=%d]", x, y,
00171 v(0,0).R(), v(0,0).G(),v(0,0).B() );
00172 return;
00173 }
00174 else if (n_p==4) {
00175 vcl_sprintf(msg, "(%d, %d) Pixel type not Available", x, y);
00176 return;
00177 }
00178 return;
00179 }
00180 case VIL_PIXEL_FORMAT_UINT_16:
00181 {
00182 if (n_p==1)
00183 {
00184 vil_image_view<vxl_uint_16> v = r->get_view(x,1,y,1);
00185 if (!v)
00186 vcl_sprintf(msg, "Pixel Not Available");
00187 else
00188 vcl_sprintf(msg, "(%d, %d) (uint16) %d", x, y, v(0,0));
00189 return;
00190 }
00191 else if (n_p==3)
00192 {
00193 vil_image_view<vil_rgb<vxl_uint_16> > v = r->get_view(x,1,y,1);
00194 if (!v)
00195 vcl_sprintf(msg, "Pixel Not Available");
00196 else
00197 vcl_sprintf(msg, "(%d, %d) (uint16)[ R=%d,G=%d,B=%d]", x, y,
00198 v(0,0).R(), v(0,0).G(),v(0,0).B() );
00199 }
00200 else if (n_p==4)
00201 {
00202 vil_image_view<vil_rgba<vxl_uint_16> > v = r->get_view(x,1,y,1);
00203 if (!v) {
00204 vcl_sprintf(msg, "Pixel Not Available");
00205 return;
00206 }
00207 else
00208 {
00209 int band_map = 0;
00210 if (rmp_)
00211 band_map = rmp_->band_map_;
00212 switch (band_map)
00213 {
00214 case vgui_range_map_params::RGB_m :
00215 vcl_sprintf(msg, "(%d, %d) (RGB:uint16)[ R=%d,G=%d,B=%d,I=%d]",
00216 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
00217 break;
00218 case vgui_range_map_params::XRG_m :
00219 vcl_sprintf(msg, "(%d, %d) (IRG:uint16)[ R=%d,G=%d,B=%d,I=%d]",
00220 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
00221 break;
00222 case vgui_range_map_params::RXB_m :
00223 vcl_sprintf(msg, "(%d, %d) (RIB:uint16)[ R=%d,G=%d,B=%d,I=%d]",
00224 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
00225 break;
00226 case vgui_range_map_params::RGX_m :
00227 vcl_sprintf(msg, "(%d, %d) (RGI:uint16)[ R=%d,G=%d,B=%d,I=%d]",
00228 x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
00229 break;
00230 default:
00231 vcl_sprintf(msg, "Pixel Not Available");
00232 return;
00233 }
00234 }
00235 }
00236 }
00237 case VIL_PIXEL_FORMAT_INT_16: {
00238 if (n_p==1)
00239 {
00240 vil_image_view<vxl_int_16> v = r->get_view(x,1,y,1);
00241 if (!v)
00242 vcl_sprintf(msg, "Pixel Not Available");
00243 else
00244 vcl_sprintf(msg, "(%d, %d) (int16) %d", x, y, v(0,0));
00245 return;
00246 }
00247 else if (n_p==3)
00248 {
00249 vil_image_view<vil_rgb<vxl_int_16> > v = r->get_view(x,1,y,1);
00250 if (!v)
00251 vcl_sprintf(msg, "Pixel Not Available");
00252 else
00253 vcl_sprintf(msg, "(%d, %d) (int16)[ R=%d,G=%d,B=%d]", x, y,
00254 v(0,0).R(), v(0,0).G(),v(0,0).B() );
00255 return;
00256 }
00257 return;
00258 }
00259 case VIL_PIXEL_FORMAT_UINT_32: {
00260 if (n_p==1)
00261 {
00262 vil_image_view<vxl_uint_32> v = r->get_view(x,1,y,1);
00263 if (!v)
00264 vcl_sprintf(msg, "Pixel Not Available");
00265 else
00266 vcl_sprintf(msg, "(%d, %d) (uint32) %d", x, y, v(0,0));
00267 return;
00268 }
00269 else if (n_p==3)
00270 {
00271 vil_image_view<vil_rgb<vxl_uint_32> > v = r->get_view(x,1,y,1);
00272 if (!v)
00273 vcl_sprintf(msg, "Pixel Not Available");
00274 else
00275 vcl_sprintf(msg, "(%d, %d) (uint32)[ R=%d,G=%d,B=%d]", x, y,
00276 v(0,0).R(), v(0,0).G(),v(0,0).B() );
00277 return;
00278 }
00279 return;
00280 }
00281 case VIL_PIXEL_FORMAT_FLOAT: {
00282 vil_image_view<float> v = r->get_view(x,1,y,1);
00283 if (!v)
00284 vcl_sprintf(msg, "Pixel Not Available");
00285 else if (n_p == 1)
00286 vcl_sprintf(msg, "(%d, %d) (float) %f", x, y, v(0,0));
00287 else if (n_p ==3)
00288 vcl_sprintf(msg, "(%d, %d) (float)[ R=%6.3f,G=%6.3f,B=%6.3f]", x, y,
00289 v(0,0,0), v(0,0,1), v(0,0,2) );
00290 return;
00291 }
00292 case VIL_PIXEL_FORMAT_DOUBLE: {
00293 vil_image_view<double> v = r->get_view(x,1,y,1);
00294 if (!v)
00295 vcl_sprintf(msg, "Pixel Not Available");
00296 else
00297 vcl_sprintf(msg, "(%d, %d) (double) %g", x, y, v(0,0));
00298 return;
00299 }
00300 case VIL_PIXEL_FORMAT_RGB_BYTE: {
00301 vil_image_view<vil_rgb<vxl_byte> > v = r->get_view(x,1,y,1);
00302 if (!v)
00303 vcl_sprintf(msg, "Pixel Not Available");
00304 else
00305 vcl_sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d]", x, y,
00306 v(0,0).R(), v(0,0).G(),v(0,0).B() );
00307 return;
00308 }
00309 case VIL_PIXEL_FORMAT_RGB_UINT_16: {
00310 vil_image_view<vil_rgb<vxl_uint_16> > v = r->get_view(x,1,y,1);
00311 if (!v)
00312 vcl_sprintf(msg, "Pixel Not Available");
00313 else
00314 vcl_sprintf(msg, "(%d, %d) (uint16)[ R=%d,G=%d,B=%d]", x, y,
00315 v(0,0).R(), v(0,0).G(),v(0,0).B() );
00316 return;
00317 }
00318 #if 0
00319 case VIL_PIXEL_FORMAT_UINT_32:
00320 case VIL_PIXEL_FORMAT_INT_32:
00321 case VIL_PIXEL_FORMAT_RGB_SBYTE:
00322 case VIL_PIXEL_FORMAT_RGB_INT_16:
00323 case VIL_PIXEL_FORMAT_RGB_UINT_32:
00324 case VIL_PIXEL_FORMAT_RGB_INT_32:
00325 case VIL_PIXEL_FORMAT_RGB_FLOAT:
00326 case VIL_PIXEL_FORMAT_RGB_DOUBLE:
00327 case VIL_PIXEL_FORMAT_RGBA_UINT_32:
00328 case VIL_PIXEL_FORMAT_RGBA_INT_32:
00329 case VIL_PIXEL_FORMAT_RGBA_UINT_16:
00330 case VIL_PIXEL_FORMAT_RGBA_INT_16:
00331 case VIL_PIXEL_FORMAT_RGBA_BYTE:
00332 case VIL_PIXEL_FORMAT_RGBA_SBYTE:
00333 case VIL_PIXEL_FORMAT_RGBA_FLOAT:
00334 case VIL_PIXEL_FORMAT_RGBA_DOUBLE:
00335 case VIL_PIXEL_FORMAT_COMPLEX_FLOAT:
00336 case VIL_PIXEL_FORMAT_COMPLEX_DOUBLE:
00337 #endif
00338 default:
00339 vcl_sprintf(msg, "Pixel Not Available");
00340 }
00341 }
00342
00343 double bgui_image_tableau::
00344 get_pixel_value(const unsigned c, const unsigned r)
00345 {
00346 vil_image_resource_sptr rs = this->get_image_resource();
00347 if (!rs)
00348 return 0;
00349 if (c>=rs->ni()||r>=rs->nj())
00350 return 0;
00351 unsigned n_p = rs->nplanes();
00352 vil_pixel_format type = rs->pixel_format();
00353 switch (type )
00354 {
00355 case VIL_PIXEL_FORMAT_BOOL: {
00356 vil_image_view<bool> v = rs->get_view();
00357 if (!v)
00358 return 0;
00359 else
00360 return static_cast<double>(v(0,0));
00361 }
00362 case VIL_PIXEL_FORMAT_BYTE: {
00363 vil_image_view<vxl_byte> v = rs->get_view(c,1,r,1);
00364 if (!v)
00365 return 0;
00366 if (n_p==1)
00367 return static_cast<double>(v(0,0));
00368 else if (n_p==3)
00369 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
00370 }
00371 case VIL_PIXEL_FORMAT_SBYTE: {
00372 vil_image_view<vxl_sbyte> v = rs->get_view(c,1,r,1);
00373 if (!v)
00374 return 0;
00375 else
00376 if (n_p==1)
00377 return static_cast<double>(v(0,0));
00378 else if (n_p==3)
00379 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
00380 }
00381 case VIL_PIXEL_FORMAT_UINT_16: {
00382 vil_image_view<vxl_uint_16> v = rs->get_view(c,1,r,1);
00383 if (!v)
00384 return 0;
00385 else
00386 if (n_p==1)
00387 return static_cast<double>(v(0,0));
00388 else if (n_p==3)
00389 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
00390 else if (n_p==4)
00391 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2)+v(0,0,3))/4;
00392 }
00393 case VIL_PIXEL_FORMAT_INT_16: {
00394 vil_image_view<vxl_int_16> v = rs->get_view(c,1,r,1);
00395 if (!v)
00396 return 0;
00397 else
00398 if (n_p==1)
00399 return static_cast<double>(v(0,0));
00400 else if (n_p==3)
00401 return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
00402 }
00403 case VIL_PIXEL_FORMAT_FLOAT: {
00404 vil_image_view<float> v = rs->get_view(c,1,r,1);
00405 if (!v)
00406 return 0;
00407 else
00408 return static_cast<double>(v(0,0));
00409 }
00410 case VIL_PIXEL_FORMAT_DOUBLE: {
00411 vil_image_view<double> v = rs->get_view(c,1,r,1);
00412 if (!v)
00413 return 0;
00414 else
00415 return v(0,0);
00416 }
00417 case VIL_PIXEL_FORMAT_RGB_BYTE: {
00418 vil_image_view<vil_rgb<vxl_byte> > v = rs->get_view(c,1,r,1);
00419 if (!v)
00420 return 0;
00421 else
00422 return static_cast<double>(v(0,0).R()+v(0,0).G()+v(0,0).B())/3;
00423 }
00424 case VIL_PIXEL_FORMAT_RGB_UINT_16: {
00425 vil_image_view<vil_rgb<vxl_uint_16> > v = rs->get_view(c,1,r,1);
00426 if (!v)
00427 return 0;
00428 else
00429 return static_cast<double>(v(0,0).R()+v(0,0).G()+v(0,0).B())/3;
00430 }
00431 default:
00432 return 0;
00433 }
00434 }
00435
00436
00437 vcl_vector<double> bgui_image_tableau::get_color_pixel_value(const unsigned c, const unsigned r)
00438 {
00439 vil_image_resource_sptr rs = this->get_image_resource();
00440 if (!rs)
00441 return vcl_vector<double>(0);
00442 if (c>=rs->ni()||r>=rs->nj())
00443 return vcl_vector<double>(0);
00444 unsigned n_p = rs->nplanes();
00445 vcl_vector<double> val(n_p, 0.0);
00446 if (n_p==1)
00447 {
00448 val[0]=this->get_pixel_value(c, r);
00449 return val;
00450 }
00451 vil_pixel_format type = rs->pixel_format();
00452 switch (type )
00453 {
00454 case VIL_PIXEL_FORMAT_BYTE: {
00455 vil_image_view<vxl_byte> v = rs->get_view(c,1,r,1);
00456 if (!v)
00457 return val;
00458 for (unsigned p = 0; p<n_p; ++p)
00459 val[p]=static_cast<double>(v(0,0,p));
00460 return val;
00461 }
00462 case VIL_PIXEL_FORMAT_UINT_16: {
00463 vil_image_view<vxl_uint_16> v = rs->get_view(c,1,r,1);
00464 if (!v)
00465 return val;
00466 for (unsigned p = 0; p<n_p; ++p)
00467 val[p]=static_cast<double>(v(0,0,p));
00468 return val;
00469 }
00470 default:
00471 return val;
00472 }
00473 }
00474
00475 void bgui_image_tableau::image_line(const float col_start,
00476 const float row_start,
00477 const float col_end,
00478 const float row_end,
00479 vcl_vector<double>& line_pos,
00480 vcl_vector<double>& vals)
00481 {
00482 line_pos.clear();vals.clear();
00483
00484
00485 float length = vcl_sqrt((col_end-col_start)*(col_end-col_start) +
00486 (row_end-row_start)*(row_end-row_start));
00487 if (length == 0)
00488 return;
00489
00490 float xstep = (col_end-col_start)/length;
00491 float ystep = (row_end-row_start)/length;
00492 float sinc = vcl_sqrt(xstep*xstep + ystep*ystep);
00493 float spos = 0;
00494 line_pos.push_back(spos);
00495 unsigned c = static_cast<unsigned>(col_start),
00496 r = static_cast<unsigned>(row_start);
00497 vals.push_back(get_pixel_value(c, r));
00498
00499
00500 float xpos = col_start, ypos = row_start;
00501 unsigned nsteps = static_cast<unsigned>(length);
00502 for (unsigned i = 0; i<nsteps; ++i)
00503 {
00504 xpos += xstep;
00505 ypos += ystep;
00506 spos += sinc;
00507 c = static_cast<unsigned>(xpos);
00508 r = static_cast<unsigned>(ypos);
00509 line_pos.push_back(spos);
00510 vals.push_back(get_pixel_value(c, r));
00511 }
00512 }
00513
00514
00515 void bgui_image_tableau::image_line(const float col_start,
00516 const float row_start,
00517 const float col_end,
00518 const float row_end,
00519 vcl_vector<double>& line_pos,
00520 vcl_vector<vcl_vector<double> >& vals)
00521 {
00522 line_pos.clear();vals.clear();
00523
00524
00525 float length = vcl_sqrt((col_end-col_start)*(col_end-col_start) +
00526 (row_end-row_start)*(row_end-row_start));
00527 if (length == 0)
00528 return;
00529
00530 float xstep = (col_end-col_start)/length;
00531 float ystep = (row_end-row_start)/length;
00532 float sinc = vcl_sqrt(xstep*xstep + ystep*ystep);
00533 float spos = 0;
00534 line_pos.push_back(spos);
00535 unsigned c = static_cast<unsigned>(col_start),
00536 r = static_cast<unsigned>(row_start);
00537 vcl_vector<double> cv = get_color_pixel_value(c, r);
00538 unsigned n_bands = cv.size();
00539 vals.resize(n_bands);
00540 for (unsigned i = 0; i<n_bands; ++i)
00541 vals[i].push_back(cv[i]);
00542
00543
00544 float xpos = col_start, ypos = row_start;
00545 unsigned nsteps = static_cast<unsigned>(length);
00546 for (unsigned i = 0; i<nsteps; ++i)
00547 {
00548 xpos += xstep;
00549 ypos += ystep;
00550 spos += sinc;
00551 c = static_cast<unsigned>(xpos);
00552 r = static_cast<unsigned>(ypos);
00553 line_pos.push_back(spos);
00554 cv = get_color_pixel_value(c, r);
00555 for (unsigned i = 0; i<n_bands; ++i)
00556 vals[i].push_back(cv[i]);
00557 }
00558 }
00559
00560
00561
00562
00563
00564 bool bgui_image_tableau::handle(vgui_event const &e)
00565 {
00566 static bool button_down = false;
00567 if (e.type == vgui_DRAW)
00568 {
00569 base::handle(e);
00570 if (tt_) tt_->handle(e);
00571 return true;
00572 }
00573
00574 if (e.type == vgui_BUTTON_DOWN)
00575 {
00576 button_down = true;
00577 if (handle_motion_)
00578 vgui::out << ' ' << vcl_endl;
00579 }
00580 else if (e.type == vgui_BUTTON_UP)
00581 {
00582 button_down = false;
00583 }
00584 else if (e.type == vgui_MOTION && handle_motion_ && !button_down)
00585 {
00586
00587 float pointx, pointy;
00588 vgui_projection_inspector p_insp;
00589 p_insp.window_to_image_coordinates(e.wx, e.wy, pointx, pointy);
00590 int intx = (int)vcl_floor(pointx), inty = (int)vcl_floor(pointy);
00591 char msg[100];
00592
00593 this->get_pixel_info_from_image(intx, inty,e, msg);
00594
00595
00596
00597
00598 bgui_image_tableau_vp_sc_snapshot snap;
00599
00600
00601 if (!locked_) {
00602 if (show_path_)
00603 vgui::out << msg << " " << this->file_name() << vcl_endl;
00604 else
00605 vgui::out << msg << vcl_endl;
00606 }
00607 }
00608 return base::handle(e);
00609 }
00610
00611