00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <core/exception.h>
00025 #include <fvutils/ipc/shm_image.h>
00026 #include <fvutils/ipc/shm_exceptions.h>
00027 #include <utils/system/console_colors.h>
00028 #include <utils/ipc/shm_exceptions.h>
00029
00030 #include <iostream>
00031 #include <cstring>
00032 #include <cstdlib>
00033 #include <cstdio>
00034
00035 using namespace std;
00036 using namespace fawkes;
00037
00038 namespace firevision {
00039 #if 0
00040 }
00041 #endif
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 SharedMemoryImageBuffer::SharedMemoryImageBuffer(const char *image_id,
00063 colorspace_t cspace,
00064 unsigned int width,
00065 unsigned int height)
00066 : SharedMemory(FIREVISION_SHM_IMAGE_MAGIC_TOKEN,
00067 false,
00068 true,
00069 true)
00070 {
00071 constructor(image_id, cspace, width, height, false);
00072 add_semaphore();
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 SharedMemoryImageBuffer::SharedMemoryImageBuffer(const char *image_id, bool is_read_only)
00087 : SharedMemory(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, is_read_only, false, false)
00088 {
00089 constructor(image_id, CS_UNKNOWN, 0, 0, is_read_only);
00090 }
00091
00092
00093 void
00094 SharedMemoryImageBuffer::constructor(const char *image_id, colorspace_t cspace,
00095 unsigned int width, unsigned int height,
00096 bool is_read_only)
00097 {
00098 _image_id = strdup(image_id);
00099 _is_read_only = is_read_only;
00100
00101 _colorspace = cspace;
00102 _width = width;
00103 _height = height;
00104
00105 priv_header = new SharedMemoryImageBufferHeader(_image_id, _colorspace, width, height);
00106 _header = priv_header;
00107 try {
00108 attach();
00109 raw_header = priv_header->raw_header();
00110 } catch (Exception &e) {
00111 e.append("SharedMemoryImageBuffer: could not attach to '%s'\n", image_id);
00112 ::free(_image_id);
00113 _image_id = NULL;
00114 delete priv_header;
00115 throw;
00116 }
00117 }
00118
00119
00120
00121 SharedMemoryImageBuffer::~SharedMemoryImageBuffer()
00122 {
00123 ::free(_image_id);
00124 delete priv_header;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134 bool
00135 SharedMemoryImageBuffer::set_image_id(const char *image_id)
00136 {
00137 free();
00138 ::free(_image_id);
00139 _image_id = strdup(image_id);
00140 priv_header->set_image_id(_image_id);
00141 attach();
00142 raw_header = priv_header->raw_header();
00143 return (_memptr != NULL);
00144 }
00145
00146
00147
00148
00149
00150 const char *
00151 SharedMemoryImageBuffer::image_id() const
00152 {
00153 return _image_id;
00154 }
00155
00156
00157
00158
00159
00160
00161 void
00162 SharedMemoryImageBuffer::capture_time(long int *sec, long int *usec) const
00163 {
00164 *sec = raw_header->capture_time_sec;
00165 *usec = raw_header->capture_time_usec;
00166 }
00167
00168
00169
00170
00171 Time
00172 SharedMemoryImageBuffer::capture_time() const
00173 {
00174 return Time(raw_header->capture_time_sec, raw_header->capture_time_usec);
00175 }
00176
00177
00178
00179
00180
00181 void
00182 SharedMemoryImageBuffer::set_capture_time(Time *time)
00183 {
00184 if (_is_read_only) {
00185 throw Exception("Buffer is read-only. Not setting capture time.");
00186 }
00187
00188 const timeval *t = time->get_timeval();
00189 raw_header->capture_time_sec = t->tv_sec;
00190 raw_header->capture_time_usec = t->tv_usec;
00191 }
00192
00193
00194
00195
00196
00197 void
00198 SharedMemoryImageBuffer::set_capture_time(long int sec, long int usec)
00199 {
00200 if (_is_read_only) {
00201 throw Exception("Buffer is read-only. Not setting capture time.");
00202 }
00203
00204 raw_header->capture_time_sec = sec;
00205 raw_header->capture_time_usec = usec;
00206 }
00207
00208
00209
00210
00211 unsigned char *
00212 SharedMemoryImageBuffer::buffer() const
00213 {
00214 return (unsigned char *)_memptr;
00215 }
00216
00217
00218
00219
00220
00221 colorspace_t
00222 SharedMemoryImageBuffer::colorspace() const
00223 {
00224 return (colorspace_t)raw_header->colorspace;
00225 }
00226
00227
00228
00229
00230
00231 unsigned int
00232 SharedMemoryImageBuffer::width() const
00233 {
00234 return raw_header->width;
00235 }
00236
00237
00238
00239
00240
00241 unsigned int
00242 SharedMemoryImageBuffer::height() const
00243 {
00244 return raw_header->height;
00245 }
00246
00247
00248
00249
00250
00251 unsigned int
00252 SharedMemoryImageBuffer::roi_x() const
00253 {
00254 return raw_header->roi_x;
00255 }
00256
00257
00258
00259
00260
00261 unsigned int
00262 SharedMemoryImageBuffer::roi_y() const
00263 {
00264 return raw_header->roi_y;
00265 }
00266
00267
00268
00269
00270
00271 unsigned int
00272 SharedMemoryImageBuffer::roi_width() const
00273 {
00274 return raw_header->roi_width;
00275 }
00276
00277
00278
00279
00280
00281 unsigned int
00282 SharedMemoryImageBuffer::roi_height() const
00283 {
00284 return raw_header->roi_height;
00285 }
00286
00287
00288
00289
00290
00291 int
00292 SharedMemoryImageBuffer::circle_x() const
00293 {
00294 return raw_header->circle_x;
00295 }
00296
00297
00298
00299
00300
00301 int
00302 SharedMemoryImageBuffer::circle_y() const
00303 {
00304 return raw_header->circle_y;
00305 }
00306
00307
00308
00309
00310
00311 unsigned int
00312 SharedMemoryImageBuffer::circle_radius() const
00313 {
00314 return raw_header->circle_radius;
00315 }
00316
00317
00318
00319
00320
00321 void
00322 SharedMemoryImageBuffer::set_roi_x(unsigned int roi_x)
00323 {
00324 if (_is_read_only) {
00325 throw Exception("Buffer is read-only. Not setting ROI X.");
00326 }
00327 raw_header->roi_x = roi_x;
00328 }
00329
00330
00331
00332
00333
00334 void
00335 SharedMemoryImageBuffer::set_roi_y(unsigned int roi_y)
00336 {
00337 if (_is_read_only) {
00338 throw Exception("Buffer is read-only. Not setting ROI Y.");
00339 }
00340 raw_header->roi_y = roi_y;
00341 }
00342
00343
00344
00345
00346
00347 void
00348 SharedMemoryImageBuffer::set_roi_width(unsigned int roi_w)
00349 {
00350 if (_is_read_only) {
00351 throw Exception("Buffer is read-only. Not setting ROI width.");
00352 }
00353 raw_header->roi_width = roi_w;
00354 }
00355
00356
00357
00358
00359
00360 void
00361 SharedMemoryImageBuffer::set_roi_height(unsigned int roi_h)
00362 {
00363 if (_is_read_only) {
00364 throw Exception("Buffer is read-only. Not setting ROI height.");
00365 }
00366 raw_header->roi_height = roi_h;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376 void
00377 SharedMemoryImageBuffer::set_roi(unsigned int roi_x, unsigned int roi_y,
00378 unsigned int roi_w, unsigned int roi_h)
00379 {
00380 if (_is_read_only) {
00381 throw Exception("Buffer is read-only. Not setting ROI X/Y.");
00382 }
00383 raw_header->roi_x = roi_x;
00384 raw_header->roi_y = roi_y;
00385 raw_header->roi_width = roi_w;
00386 raw_header->roi_height = roi_h;
00387 }
00388
00389
00390
00391
00392
00393 void
00394 SharedMemoryImageBuffer::set_circle_x(int circle_x)
00395 {
00396 if (_is_read_only) {
00397 throw Exception("Buffer is read-only. Not setting circle X.");
00398 }
00399 raw_header->circle_x = circle_x;
00400 }
00401
00402
00403
00404
00405
00406 void
00407 SharedMemoryImageBuffer::set_circle_y(int circle_y)
00408 {
00409 if (_is_read_only) {
00410 throw Exception("Buffer is read-only. Not setting circle Y.");
00411 }
00412 raw_header->circle_y = circle_y;
00413 }
00414
00415
00416
00417
00418
00419 void
00420 SharedMemoryImageBuffer::set_circle_radius(unsigned int circle_radius)
00421 {
00422 if (_is_read_only) {
00423 throw Exception("Buffer is read-only. Not setting circle radius.");
00424 }
00425 raw_header->circle_radius = circle_radius;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 void
00435 SharedMemoryImageBuffer::set_circle(int x, int y, unsigned int r)
00436 {
00437 if (_is_read_only) {
00438 throw Exception("Buffer is read-only. Not setting circle X/Y/radius.");
00439 }
00440 raw_header->circle_x = x;
00441 raw_header->circle_y = y;
00442 raw_header->circle_radius = r;
00443 }
00444
00445
00446
00447
00448
00449 void
00450 SharedMemoryImageBuffer::set_circle_found(bool found)
00451 {
00452 raw_header->flag_circle_found = (found ? 1 : 0);
00453 }
00454
00455
00456
00457
00458
00459 bool
00460 SharedMemoryImageBuffer::circle_found() const
00461 {
00462 return (raw_header->flag_circle_found == 1);
00463 }
00464
00465
00466
00467 void
00468 SharedMemoryImageBuffer::list()
00469 {
00470 SharedMemoryImageBufferLister *lister = new SharedMemoryImageBufferLister();
00471 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader();
00472
00473 SharedMemory::list(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h, lister);
00474
00475 delete lister;
00476 delete h;
00477 }
00478
00479
00480
00481
00482
00483
00484 void
00485 SharedMemoryImageBuffer::cleanup(bool use_lister)
00486 {
00487 SharedMemoryImageBufferLister *lister = NULL;
00488 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader();
00489
00490 if (use_lister) {
00491 lister = new SharedMemoryImageBufferLister();
00492 }
00493
00494 SharedMemory::erase_orphaned(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h, lister);
00495
00496 delete lister;
00497 delete h;
00498 }
00499
00500
00501
00502
00503
00504
00505 bool
00506 SharedMemoryImageBuffer::exists(const char *image_id)
00507 {
00508 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader(image_id, CS_UNKNOWN, 0, 0);
00509
00510 bool ex = SharedMemory::exists(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h);
00511
00512 delete h;
00513 return ex;
00514 }
00515
00516
00517
00518
00519
00520 void
00521 SharedMemoryImageBuffer::wipe(const char *image_id)
00522 {
00523 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader(image_id, CS_UNKNOWN, 0, 0);
00524
00525 SharedMemory::erase(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h, NULL);
00526
00527 delete h;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536 SharedMemoryImageBufferHeader::SharedMemoryImageBufferHeader()
00537 {
00538 _colorspace = CS_UNKNOWN;
00539 _image_id = NULL;
00540 _width = 0;
00541 _height = 0;
00542 _header = NULL;
00543 _orig_image_id = NULL;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553 SharedMemoryImageBufferHeader::SharedMemoryImageBufferHeader(const char *image_id,
00554 colorspace_t colorspace,
00555 unsigned int width,
00556 unsigned int height)
00557 {
00558 _image_id = strdup(image_id);
00559 _colorspace = colorspace;
00560 _width = width;
00561 _height = height;
00562 _header = NULL;
00563
00564 _orig_image_id = NULL;
00565 _orig_width = 0;
00566 _orig_height = 0;
00567 _orig_colorspace = CS_UNKNOWN;
00568 }
00569
00570
00571
00572
00573
00574 SharedMemoryImageBufferHeader::SharedMemoryImageBufferHeader(const SharedMemoryImageBufferHeader *h)
00575 {
00576 if ( h->_image_id != NULL ) {
00577 _image_id = strdup(h->_image_id);
00578 } else {
00579 _image_id = NULL;
00580 }
00581 _colorspace = h->_colorspace;
00582 _width = h->_width;
00583 _height = h->_height;
00584 _header = h->_header;
00585
00586 _orig_image_id = NULL;
00587 _orig_width = 0;
00588 _orig_height = 0;
00589 _orig_colorspace = CS_UNKNOWN;
00590 }
00591
00592
00593
00594 SharedMemoryImageBufferHeader::~SharedMemoryImageBufferHeader()
00595 {
00596 if ( _image_id != NULL) free(_image_id);
00597 if ( _orig_image_id != NULL) free(_orig_image_id);
00598 }
00599
00600
00601 size_t
00602 SharedMemoryImageBufferHeader::size()
00603 {
00604 return sizeof(SharedMemoryImageBuffer_header_t);
00605 }
00606
00607
00608 SharedMemoryHeader *
00609 SharedMemoryImageBufferHeader::clone() const
00610 {
00611 return new SharedMemoryImageBufferHeader(this);
00612 }
00613
00614
00615 size_t
00616 SharedMemoryImageBufferHeader::data_size()
00617 {
00618 if (_header == NULL) {
00619 return colorspace_buffer_size(_colorspace, _width, _height);
00620 } else {
00621 return colorspace_buffer_size((colorspace_t)_header->colorspace, _header->width, _header->height);
00622 }
00623 }
00624
00625
00626 bool
00627 SharedMemoryImageBufferHeader::matches(void *memptr)
00628 {
00629 SharedMemoryImageBuffer_header_t *h = (SharedMemoryImageBuffer_header_t *)memptr;
00630
00631 if (_image_id == NULL) {
00632 return true;
00633
00634 } else if (strncmp(h->image_id, _image_id, IMAGE_ID_MAX_LENGTH) == 0) {
00635
00636 if ( (_colorspace == CS_UNKNOWN) ||
00637 (((colorspace_t)h->colorspace == _colorspace) &&
00638 (h->width == _width) &&
00639 (h->height == _height)
00640 )
00641 ) {
00642 return true;
00643 } else {
00644 throw InconsistentImageException("Inconsistent image found in memory (meta)");
00645 }
00646 } else {
00647 return false;
00648 }
00649 }
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 bool
00661 SharedMemoryImageBufferHeader::operator==(const SharedMemoryHeader &s) const
00662 {
00663 const SharedMemoryImageBufferHeader *h = dynamic_cast<const SharedMemoryImageBufferHeader *>(&s);
00664 if ( ! h ) {
00665 return false;
00666 } else {
00667 return ( (strncmp(_image_id, h->_image_id, IMAGE_ID_MAX_LENGTH) == 0) &&
00668 (_colorspace == h->_colorspace) &&
00669 (_width == h->_width) &&
00670 (_height == h->_height) );
00671 }
00672 }
00673
00674
00675 void
00676 SharedMemoryImageBufferHeader::print_info()
00677 {
00678 if (_image_id == NULL) {
00679 cout << "No image set" << endl;
00680 return;
00681 }
00682 cout << "SharedMemory Image Info: " << endl;
00683 printf(" address: %p\n", _header);
00684 cout << " image id: " << _image_id << endl
00685 << " colorspace: " << _colorspace << endl
00686 << " dimensions: " << _width << "x" << _height << endl;
00687
00688
00689
00690
00691
00692
00693
00694
00695 }
00696
00697
00698
00699
00700
00701 bool
00702 SharedMemoryImageBufferHeader::create()
00703 {
00704 return ( (_colorspace != CS_UNKNOWN) &&
00705 (_width > 0) &&
00706 (_height > 0) );
00707 }
00708
00709
00710 void
00711 SharedMemoryImageBufferHeader::initialize(void *memptr)
00712 {
00713 SharedMemoryImageBuffer_header_t *header = (SharedMemoryImageBuffer_header_t *)memptr;
00714 memset(memptr, 0, sizeof(SharedMemoryImageBuffer_header_t));
00715
00716 strncpy(header->image_id, _image_id, IMAGE_ID_MAX_LENGTH);
00717 header->colorspace = _colorspace;
00718 header->width = _width;
00719 header->height = _height;
00720
00721 _header = header;
00722 }
00723
00724
00725 void
00726 SharedMemoryImageBufferHeader::set(void *memptr)
00727 {
00728 SharedMemoryImageBuffer_header_t *header = (SharedMemoryImageBuffer_header_t *)memptr;
00729 if ( NULL != _orig_image_id ) free(_orig_image_id);
00730 if ( NULL != _image_id ) {
00731 _orig_image_id = strdup(_image_id);
00732 free(_image_id);
00733 } else {
00734 _orig_image_id = NULL;
00735 }
00736 _orig_width = _width;
00737 _orig_height = _height;
00738 _orig_colorspace = _colorspace;
00739 _header = header;
00740
00741 _image_id = strndup(header->image_id, IMAGE_ID_MAX_LENGTH);
00742 _width = header->width;
00743 _height = header->height;
00744 _colorspace = (colorspace_t)header->colorspace;
00745 }
00746
00747
00748 void
00749 SharedMemoryImageBufferHeader::reset()
00750 {
00751 if ( NULL != _image_id ) {
00752 free(_image_id);
00753 _image_id = NULL;
00754 }
00755 if ( _orig_image_id != NULL ) {
00756 _image_id = strdup(_orig_image_id);
00757 }
00758 _width =_orig_width;
00759 _height =_orig_height;
00760 _colorspace =_orig_colorspace;
00761 _header = NULL;
00762 }
00763
00764
00765
00766
00767
00768 colorspace_t
00769 SharedMemoryImageBufferHeader::colorspace() const
00770 {
00771 if ( _header) return (colorspace_t)_header->colorspace;
00772 else return _colorspace;
00773 }
00774
00775
00776
00777
00778
00779 unsigned int
00780 SharedMemoryImageBufferHeader::width() const
00781 {
00782 if ( _header) return _header->width;
00783 else return _width;
00784 }
00785
00786
00787
00788
00789
00790 unsigned int
00791 SharedMemoryImageBufferHeader::height() const
00792 {
00793 if ( _header) return _header->height;
00794 else return _height;
00795 }
00796
00797
00798
00799
00800
00801 const char *
00802 SharedMemoryImageBufferHeader::image_id() const
00803 {
00804 return _image_id;
00805 }
00806
00807
00808
00809
00810
00811 void
00812 SharedMemoryImageBufferHeader::set_image_id(const char *image_id)
00813 {
00814 if ( _image_id != NULL) ::free(_image_id);
00815 _image_id = strdup(image_id);
00816 }
00817
00818
00819
00820
00821
00822 SharedMemoryImageBuffer_header_t *
00823 SharedMemoryImageBufferHeader::raw_header()
00824 {
00825 return _header;
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 SharedMemoryImageBufferLister::SharedMemoryImageBufferLister()
00835 {
00836 }
00837
00838
00839
00840 SharedMemoryImageBufferLister::~SharedMemoryImageBufferLister()
00841 {
00842 }
00843
00844
00845 void
00846 SharedMemoryImageBufferLister::print_header()
00847 {
00848 cout << endl << cgreen << "FireVision Shared Memory Segments - Images" << cnormal << endl
00849 << "========================================================================================" << endl
00850 << cdarkgray;
00851 printf ("%-20s %-10s %-10s %-9s %-16s %-5s %-5s %s\n",
00852 "Image ID", "ShmID", "Semaphore", "Bytes", "Color Space", "Width", "Height",
00853 "State");
00854 cout << cnormal
00855 << "----------------------------------------------------------------------------------------" << endl;
00856 }
00857
00858
00859 void
00860 SharedMemoryImageBufferLister::print_footer()
00861 {
00862 }
00863
00864
00865 void
00866 SharedMemoryImageBufferLister::print_no_segments()
00867 {
00868 cout << "No FireVision shared memory segments found" << endl;
00869 }
00870
00871
00872 void
00873 SharedMemoryImageBufferLister::print_no_orphaned_segments()
00874 {
00875 cout << "No orphaned FireVision shared memory segments found" << endl;
00876 }
00877
00878
00879 void
00880 SharedMemoryImageBufferLister::print_info(const SharedMemoryHeader *header,
00881 int shm_id, int semaphore,
00882 unsigned int mem_size,
00883 const void *memptr)
00884 {
00885
00886 SharedMemoryImageBufferHeader *h = (SharedMemoryImageBufferHeader *)header;
00887
00888 const char *colorspace = colorspace_to_string(h->colorspace());
00889
00890 printf("%-20s %-10d %-10d %-9u %-16s %-5u %-5u %s%s\n",
00891 h->image_id(), shm_id, semaphore, mem_size, colorspace,
00892 h->width(), h->height(),
00893 (SharedMemory::is_swapable(shm_id) ? "S" : ""),
00894 (SharedMemory::is_destroyed(shm_id) ? "D" : "")
00895 );
00896 }
00897
00898 }