Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * shm_image.cpp - shared memory image buffer 00004 * 00005 * Created: Thu Jan 12 14:10:43 2006 00006 * Copyright 2005-2009 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 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 #include <utils/misc/strndup.h> 00030 00031 #include <iostream> 00032 #include <cstring> 00033 #include <cstdlib> 00034 #include <cstdio> 00035 00036 using namespace std; 00037 using namespace fawkes; 00038 00039 namespace firevision { 00040 #if 0 /* just to make Emacs auto-indent happy */ 00041 } 00042 #endif 00043 00044 /** @class SharedMemoryImageBuffer <fvutils/ipc/shm_image.h> 00045 * Shared memory image buffer. 00046 * Write images to or retrieve images from a shared memory segment. 00047 * @author Tim Niemueller 00048 */ 00049 00050 /** Write Constructor. 00051 * Create a new shared memory segment. Will open a shared memory segment that 00052 * exactly fits the given information. Will throw an error if image with id 00053 * image_id exists. 00054 * I will create a new segment if no matching segment was found. 00055 * The segment is accessed in read-write mode. 00056 * 00057 * Use this constructor to open a shared memory image buffer for writing. 00058 * @param image_id image ID to open 00059 * @param cspace colorspace 00060 * @param width image width 00061 * @param height image height 00062 */ 00063 SharedMemoryImageBuffer::SharedMemoryImageBuffer(const char *image_id, 00064 colorspace_t cspace, 00065 unsigned int width, 00066 unsigned int height) 00067 : SharedMemory(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, 00068 /* read-only */ false, 00069 /* create */ true, 00070 /* destroy on delete */ true) 00071 { 00072 constructor(image_id, cspace, width, height, false); 00073 add_semaphore(); 00074 } 00075 00076 00077 /** Read Constructor. 00078 * This constructor is used to search for an existing shared memory segment. 00079 * It will throw an error if it cannot find a segment with the specified data. 00080 * The segment is opened read-only by default, but this can be overridden with 00081 * the is_read_only argument if needed. 00082 * 00083 * Use this constructor to open an image for reading. 00084 * @param image_id Image ID to open 00085 * @param is_read_only true to open image read-only 00086 */ 00087 SharedMemoryImageBuffer::SharedMemoryImageBuffer(const char *image_id, bool is_read_only) 00088 : SharedMemory(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, is_read_only, /* create */ false, /* destroy */ false) 00089 { 00090 constructor(image_id, CS_UNKNOWN, 0, 0, is_read_only); 00091 } 00092 00093 00094 void 00095 SharedMemoryImageBuffer::constructor(const char *image_id, colorspace_t cspace, 00096 unsigned int width, unsigned int height, 00097 bool is_read_only) 00098 { 00099 _image_id = strdup(image_id); 00100 _is_read_only = is_read_only; 00101 00102 _colorspace = cspace; 00103 _width = width; 00104 _height = height; 00105 00106 priv_header = new SharedMemoryImageBufferHeader(_image_id, _colorspace, width, height); 00107 _header = priv_header; 00108 try { 00109 attach(); 00110 raw_header = priv_header->raw_header(); 00111 } catch (Exception &e) { 00112 e.append("SharedMemoryImageBuffer: could not attach to '%s'\n", image_id); 00113 ::free(_image_id); 00114 _image_id = NULL; 00115 delete priv_header; 00116 throw; 00117 } 00118 } 00119 00120 00121 /** Destructor. */ 00122 SharedMemoryImageBuffer::~SharedMemoryImageBuffer() 00123 { 00124 ::free(_image_id); 00125 delete priv_header; 00126 } 00127 00128 00129 /** Set image number. 00130 * This will close the currently opened image and will try to open the new 00131 * image. This operation should be avoided. 00132 * @param image_id new image ID 00133 * @return true on success 00134 */ 00135 bool 00136 SharedMemoryImageBuffer::set_image_id(const char *image_id) 00137 { 00138 free(); 00139 ::free(_image_id); 00140 _image_id = strdup(image_id); 00141 priv_header->set_image_id(_image_id); 00142 attach(); 00143 raw_header = priv_header->raw_header(); 00144 return (_memptr != NULL); 00145 } 00146 00147 00148 /** Set frame ID. 00149 * @param frame_id new frame ID 00150 */ 00151 void 00152 SharedMemoryImageBuffer::set_frame_id(const char *frame_id) 00153 { 00154 priv_header->set_frame_id(frame_id); 00155 strncpy(raw_header->frame_id, frame_id, FRAME_ID_MAX_LENGTH); 00156 } 00157 00158 00159 /** Get Image ID. 00160 * @return image id 00161 */ 00162 const char * 00163 SharedMemoryImageBuffer::image_id() const 00164 { 00165 return _image_id; 00166 } 00167 00168 00169 /** Get frame ID. 00170 * @return frame id 00171 */ 00172 const char * 00173 SharedMemoryImageBuffer::frame_id() const 00174 { 00175 return priv_header->frame_id(); 00176 } 00177 00178 00179 /** Get the time when the image was captured. 00180 * @param sec upon return contains the seconds part of the time 00181 * @param usec upon return contains the micro seconds part of the time 00182 */ 00183 void 00184 SharedMemoryImageBuffer::capture_time(long int *sec, long int *usec) const 00185 { 00186 *sec = raw_header->capture_time_sec; 00187 *usec = raw_header->capture_time_usec; 00188 } 00189 00190 /** Get the time when the image was captured. 00191 * @return capture time 00192 */ 00193 Time 00194 SharedMemoryImageBuffer::capture_time() const 00195 { 00196 return Time(raw_header->capture_time_sec, raw_header->capture_time_usec); 00197 } 00198 00199 00200 /** Set the capture time. 00201 * @param time capture time 00202 */ 00203 void 00204 SharedMemoryImageBuffer::set_capture_time(Time *time) 00205 { 00206 if (_is_read_only) { 00207 throw Exception("Buffer is read-only. Not setting capture time."); 00208 } 00209 00210 const timeval *t = time->get_timeval(); 00211 raw_header->capture_time_sec = t->tv_sec; 00212 raw_header->capture_time_usec = t->tv_usec; 00213 } 00214 00215 /** Set the capture time. 00216 * @param sec seconds part of capture time 00217 * @param usec microseconds part of capture time 00218 */ 00219 void 00220 SharedMemoryImageBuffer::set_capture_time(long int sec, long int usec) 00221 { 00222 if (_is_read_only) { 00223 throw Exception("Buffer is read-only. Not setting capture time."); 00224 } 00225 00226 raw_header->capture_time_sec = sec; 00227 raw_header->capture_time_usec = usec; 00228 } 00229 00230 /** Get image buffer. 00231 * @return image buffer. 00232 */ 00233 unsigned char * 00234 SharedMemoryImageBuffer::buffer() const 00235 { 00236 return (unsigned char *)_memptr; 00237 } 00238 00239 00240 /** Get color space. 00241 * @return colorspace 00242 */ 00243 colorspace_t 00244 SharedMemoryImageBuffer::colorspace() const 00245 { 00246 return (colorspace_t)raw_header->colorspace; 00247 } 00248 00249 00250 /** Get image width. 00251 * @return width 00252 */ 00253 unsigned int 00254 SharedMemoryImageBuffer::width() const 00255 { 00256 return raw_header->width; 00257 } 00258 00259 00260 /** Get image height. 00261 * @return image height 00262 */ 00263 unsigned int 00264 SharedMemoryImageBuffer::height() const 00265 { 00266 return raw_header->height; 00267 } 00268 00269 00270 /** Get ROI X. 00271 * @return ROI X 00272 */ 00273 unsigned int 00274 SharedMemoryImageBuffer::roi_x() const 00275 { 00276 return raw_header->roi_x; 00277 } 00278 00279 00280 /** Get ROI Y. 00281 * @return ROI Y 00282 */ 00283 unsigned int 00284 SharedMemoryImageBuffer::roi_y() const 00285 { 00286 return raw_header->roi_y; 00287 } 00288 00289 00290 /** Get ROI width. 00291 * @return ROI width 00292 */ 00293 unsigned int 00294 SharedMemoryImageBuffer::roi_width() const 00295 { 00296 return raw_header->roi_width; 00297 } 00298 00299 00300 /** Get ROI height. 00301 * @return ROI height 00302 */ 00303 unsigned int 00304 SharedMemoryImageBuffer::roi_height() const 00305 { 00306 return raw_header->roi_height; 00307 } 00308 00309 00310 /** Get circle X. 00311 * @return circle X 00312 */ 00313 int 00314 SharedMemoryImageBuffer::circle_x() const 00315 { 00316 return raw_header->circle_x; 00317 } 00318 00319 00320 /** Get circle Y. 00321 * @return circle Y 00322 */ 00323 int 00324 SharedMemoryImageBuffer::circle_y() const 00325 { 00326 return raw_header->circle_y; 00327 } 00328 00329 00330 /** Get circle radius. 00331 * @return circle radius 00332 */ 00333 unsigned int 00334 SharedMemoryImageBuffer::circle_radius() const 00335 { 00336 return raw_header->circle_radius; 00337 } 00338 00339 00340 /** Set ROI X. 00341 * @param roi_x new ROI X 00342 */ 00343 void 00344 SharedMemoryImageBuffer::set_roi_x(unsigned int roi_x) 00345 { 00346 if (_is_read_only) { 00347 throw Exception("Buffer is read-only. Not setting ROI X."); 00348 } 00349 raw_header->roi_x = roi_x; 00350 } 00351 00352 00353 /** Set ROI Y. 00354 * @param roi_y new ROI Y 00355 */ 00356 void 00357 SharedMemoryImageBuffer::set_roi_y(unsigned int roi_y) 00358 { 00359 if (_is_read_only) { 00360 throw Exception("Buffer is read-only. Not setting ROI Y."); 00361 } 00362 raw_header->roi_y = roi_y; 00363 } 00364 00365 00366 /** Set ROI width. 00367 * @param roi_w new ROI width 00368 */ 00369 void 00370 SharedMemoryImageBuffer::set_roi_width(unsigned int roi_w) 00371 { 00372 if (_is_read_only) { 00373 throw Exception("Buffer is read-only. Not setting ROI width."); 00374 } 00375 raw_header->roi_width = roi_w; 00376 } 00377 00378 00379 /** Set ROI height. 00380 * @param roi_h new ROI height 00381 */ 00382 void 00383 SharedMemoryImageBuffer::set_roi_height(unsigned int roi_h) 00384 { 00385 if (_is_read_only) { 00386 throw Exception("Buffer is read-only. Not setting ROI height."); 00387 } 00388 raw_header->roi_height = roi_h; 00389 } 00390 00391 00392 /** Set ROI data. 00393 * @param roi_x new ROI X 00394 * @param roi_y new ROI Y 00395 * @param roi_w new ROI width 00396 * @param roi_h new ROI height 00397 */ 00398 void 00399 SharedMemoryImageBuffer::set_roi(unsigned int roi_x, unsigned int roi_y, 00400 unsigned int roi_w, unsigned int roi_h) 00401 { 00402 if (_is_read_only) { 00403 throw Exception("Buffer is read-only. Not setting ROI X/Y."); 00404 } 00405 raw_header->roi_x = roi_x; 00406 raw_header->roi_y = roi_y; 00407 raw_header->roi_width = roi_w; 00408 raw_header->roi_height = roi_h; 00409 } 00410 00411 00412 /** Set circle X. 00413 * @param circle_x new circle X 00414 */ 00415 void 00416 SharedMemoryImageBuffer::set_circle_x(int circle_x) 00417 { 00418 if (_is_read_only) { 00419 throw Exception("Buffer is read-only. Not setting circle X."); 00420 } 00421 raw_header->circle_x = circle_x; 00422 } 00423 00424 00425 /** Set circle Y. 00426 * @param circle_y new circle Y 00427 */ 00428 void 00429 SharedMemoryImageBuffer::set_circle_y(int circle_y) 00430 { 00431 if (_is_read_only) { 00432 throw Exception("Buffer is read-only. Not setting circle Y."); 00433 } 00434 raw_header->circle_y = circle_y; 00435 } 00436 00437 00438 /** Set circle radius. 00439 * @param circle_radius new circle radius 00440 */ 00441 void 00442 SharedMemoryImageBuffer::set_circle_radius(unsigned int circle_radius) 00443 { 00444 if (_is_read_only) { 00445 throw Exception("Buffer is read-only. Not setting circle radius."); 00446 } 00447 raw_header->circle_radius = circle_radius; 00448 } 00449 00450 00451 /** Set circle data. 00452 * @param x circle X 00453 * @param y circle Y 00454 * @param r circle radius 00455 */ 00456 void 00457 SharedMemoryImageBuffer::set_circle(int x, int y, unsigned int r) 00458 { 00459 if (_is_read_only) { 00460 throw Exception("Buffer is read-only. Not setting circle X/Y/radius."); 00461 } 00462 raw_header->circle_x = x; 00463 raw_header->circle_y = y; 00464 raw_header->circle_radius = r; 00465 } 00466 00467 00468 /** Set circle found. 00469 * @param found true if circle found 00470 */ 00471 void 00472 SharedMemoryImageBuffer::set_circle_found(bool found) 00473 { 00474 raw_header->flag_circle_found = (found ? 1 : 0); 00475 } 00476 00477 00478 /** Check if circle was found . 00479 * @return true if circle was found, false otherwise 00480 */ 00481 bool 00482 SharedMemoryImageBuffer::circle_found() const 00483 { 00484 return (raw_header->flag_circle_found == 1); 00485 } 00486 00487 00488 /** List all shared memory segments that contain a FireVision image. */ 00489 void 00490 SharedMemoryImageBuffer::list() 00491 { 00492 SharedMemoryImageBufferLister *lister = new SharedMemoryImageBufferLister(); 00493 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader(); 00494 00495 SharedMemory::list(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h, lister); 00496 00497 delete lister; 00498 delete h; 00499 } 00500 00501 00502 /** Erase all shared memory segments that contain FireVision images. 00503 * @param use_lister if true a lister is used to print the shared memory segments 00504 * to stdout while cleaning up. 00505 */ 00506 void 00507 SharedMemoryImageBuffer::cleanup(bool use_lister) 00508 { 00509 SharedMemoryImageBufferLister *lister = NULL; 00510 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader(); 00511 00512 if (use_lister) { 00513 lister = new SharedMemoryImageBufferLister(); 00514 } 00515 00516 SharedMemory::erase_orphaned(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h, lister); 00517 00518 delete lister; 00519 delete h; 00520 } 00521 00522 00523 /** Check image availability. 00524 * @param image_id image ID to check 00525 * @return true if shared memory segment with requested image exists 00526 */ 00527 bool 00528 SharedMemoryImageBuffer::exists(const char *image_id) 00529 { 00530 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader(image_id, CS_UNKNOWN, 0, 0); 00531 00532 bool ex = SharedMemory::exists(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h); 00533 00534 delete h; 00535 return ex; 00536 } 00537 00538 00539 /** Erase a specific shared memory segment that contains an image. 00540 * @param image_id ID of image to wipe 00541 */ 00542 void 00543 SharedMemoryImageBuffer::wipe(const char *image_id) 00544 { 00545 SharedMemoryImageBufferHeader *h = new SharedMemoryImageBufferHeader(image_id, CS_UNKNOWN, 0, 0); 00546 00547 SharedMemory::erase(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h, NULL); 00548 00549 delete h; 00550 } 00551 00552 00553 /** @class SharedMemoryImageBufferHeader <fvutils/ipc/shm_image.h> 00554 * Shared memory image buffer header. 00555 */ 00556 00557 /** Constructor. */ 00558 SharedMemoryImageBufferHeader::SharedMemoryImageBufferHeader() 00559 { 00560 _colorspace = CS_UNKNOWN; 00561 _image_id = NULL; 00562 _frame_id = NULL; 00563 _width = 0; 00564 _height = 0; 00565 _header = NULL; 00566 _orig_image_id = NULL; 00567 _orig_frame_id = NULL; 00568 } 00569 00570 00571 /** Constructor. 00572 * @param image_id image id 00573 * @param colorspace colorspace 00574 * @param width width 00575 * @param height height 00576 */ 00577 SharedMemoryImageBufferHeader::SharedMemoryImageBufferHeader(const char *image_id, 00578 colorspace_t colorspace, 00579 unsigned int width, 00580 unsigned int height) 00581 { 00582 _image_id = strdup(image_id); 00583 _colorspace = colorspace; 00584 _width = width; 00585 _height = height; 00586 _header = NULL; 00587 _frame_id = NULL; 00588 00589 _orig_image_id = NULL; 00590 _orig_frame_id = NULL; 00591 _orig_width = 0; 00592 _orig_height = 0; 00593 _orig_colorspace = CS_UNKNOWN; 00594 } 00595 00596 00597 /** Copy constructor. 00598 * @param h shared memory image header to copy 00599 */ 00600 SharedMemoryImageBufferHeader::SharedMemoryImageBufferHeader(const SharedMemoryImageBufferHeader *h) 00601 { 00602 if ( h->_image_id != NULL ) { 00603 _image_id = strdup(h->_image_id); 00604 } else { 00605 _image_id = NULL; 00606 } 00607 if ( h->_frame_id != NULL ) { 00608 _frame_id = strdup(h->_frame_id); 00609 } else { 00610 _frame_id = NULL; 00611 } 00612 _colorspace = h->_colorspace; 00613 _width = h->_width; 00614 _height = h->_height; 00615 _header = h->_header; 00616 00617 _orig_image_id = NULL; 00618 _orig_frame_id = NULL; 00619 _orig_width = 0; 00620 _orig_height = 0; 00621 _orig_colorspace = CS_UNKNOWN; 00622 } 00623 00624 00625 /** Destructor. */ 00626 SharedMemoryImageBufferHeader::~SharedMemoryImageBufferHeader() 00627 { 00628 if ( _image_id != NULL) free(_image_id); 00629 if ( _frame_id != NULL) free(_frame_id); 00630 if ( _orig_image_id != NULL) free(_orig_image_id); 00631 if ( _orig_frame_id != NULL) free(_orig_frame_id); 00632 } 00633 00634 00635 size_t 00636 SharedMemoryImageBufferHeader::size() 00637 { 00638 return sizeof(SharedMemoryImageBuffer_header_t); 00639 } 00640 00641 00642 SharedMemoryHeader * 00643 SharedMemoryImageBufferHeader::clone() const 00644 { 00645 return new SharedMemoryImageBufferHeader(this); 00646 } 00647 00648 00649 size_t 00650 SharedMemoryImageBufferHeader::data_size() 00651 { 00652 if (_header == NULL) { 00653 return colorspace_buffer_size(_colorspace, _width, _height); 00654 } else { 00655 return colorspace_buffer_size((colorspace_t)_header->colorspace, _header->width, _header->height); 00656 } 00657 } 00658 00659 00660 bool 00661 SharedMemoryImageBufferHeader::matches(void *memptr) 00662 { 00663 SharedMemoryImageBuffer_header_t *h = (SharedMemoryImageBuffer_header_t *)memptr; 00664 00665 if (_image_id == NULL) { 00666 return true; 00667 00668 } else if (strncmp(h->image_id, _image_id, IMAGE_ID_MAX_LENGTH) == 0) { 00669 if ( (_colorspace == CS_UNKNOWN) || 00670 (((colorspace_t)h->colorspace == _colorspace) && 00671 (h->width == _width) && 00672 (h->height == _height) && 00673 (! _frame_id || (strncmp(h->frame_id, _frame_id, FRAME_ID_MAX_LENGTH) == 0)) 00674 ) 00675 ) 00676 { 00677 return true; 00678 } else { 00679 throw InconsistentImageException("Inconsistent image found in memory (meta)"); 00680 } 00681 } else { 00682 return false; 00683 } 00684 } 00685 00686 /** Check for equality of headers. 00687 * First checks if passed SharedMemoryHeader is an instance of 00688 * SharedMemoryImageBufferHeader. If not returns false, otherwise it compares 00689 * image ID, colorspace, width, and height. If all match returns true, false 00690 * if any of them differs. 00691 * @param s shared memory header to compare to 00692 * @return true if the two instances identify the very same shared memory segments, 00693 * false otherwise 00694 */ 00695 bool 00696 SharedMemoryImageBufferHeader::operator==(const SharedMemoryHeader &s) const 00697 { 00698 const SharedMemoryImageBufferHeader *h = dynamic_cast<const SharedMemoryImageBufferHeader *>(&s); 00699 if ( ! h ) { 00700 return false; 00701 } else { 00702 return ( (strncmp(_image_id, h->_image_id, IMAGE_ID_MAX_LENGTH) == 0) && 00703 (! _frame_id || (strncmp(_frame_id, h->_frame_id, FRAME_ID_MAX_LENGTH) == 0)) && 00704 (_colorspace == h->_colorspace) && 00705 (_width == h->_width) && 00706 (_height == h->_height) ); 00707 } 00708 } 00709 00710 /** Print some info. */ 00711 void 00712 SharedMemoryImageBufferHeader::print_info() 00713 { 00714 if (_image_id == NULL) { 00715 cout << "No image set" << endl; 00716 return; 00717 } 00718 cout << "SharedMemory Image Info: " << endl; 00719 printf(" address: %p\n", _header); 00720 cout << " image id: " << _image_id << endl 00721 << " frame id: " << (_frame_id ? _frame_id : "NOT SET") << endl 00722 << " colorspace: " << _colorspace << endl 00723 << " dimensions: " << _width << "x" << _height << endl; 00724 /* 00725 << " ROI: at (" << header->roi_x << "," << header->roi_y 00726 << ") dim " << header->roi_width << "x" << header->roi_height << endl 00727 << " circle: " << (header->flag_circle_found ? "" : "not ") 00728 << "found at (" << header->circle_x << "," << header->circle_y 00729 << ") radius " << header->circle_radius << endl 00730 << " img ready: " << (header->flag_image_ready ? "yes" : "no") << endl; 00731 */ 00732 } 00733 00734 00735 /** Create if colorspace, width and height have been supplied. 00736 * @return true if colorspace has been set, width and height are greater than zero. 00737 */ 00738 bool 00739 SharedMemoryImageBufferHeader::create() 00740 { 00741 return ( (_colorspace != CS_UNKNOWN) && 00742 (_width > 0) && 00743 (_height > 0) ); 00744 } 00745 00746 00747 void 00748 SharedMemoryImageBufferHeader::initialize(void *memptr) 00749 { 00750 SharedMemoryImageBuffer_header_t *header = (SharedMemoryImageBuffer_header_t *)memptr; 00751 memset(memptr, 0, sizeof(SharedMemoryImageBuffer_header_t)); 00752 00753 strncpy(header->image_id, _image_id, IMAGE_ID_MAX_LENGTH); 00754 if (_frame_id) { 00755 strncpy(header->frame_id, _frame_id, FRAME_ID_MAX_LENGTH); 00756 } 00757 header->colorspace = _colorspace; 00758 header->width = _width; 00759 header->height = _height; 00760 00761 _header = header; 00762 } 00763 00764 00765 void 00766 SharedMemoryImageBufferHeader::set(void *memptr) 00767 { 00768 SharedMemoryImageBuffer_header_t *header = (SharedMemoryImageBuffer_header_t *)memptr; 00769 if ( NULL != _orig_image_id ) free(_orig_image_id); 00770 if ( NULL != _image_id ) { 00771 _orig_image_id = strdup(_image_id); 00772 free(_image_id); 00773 } else { 00774 _orig_image_id = NULL; 00775 } 00776 if ( NULL != _orig_frame_id ) free(_orig_frame_id); 00777 if ( NULL != _frame_id ) { 00778 _orig_frame_id = strdup(_frame_id); 00779 free(_frame_id); 00780 } else { 00781 _orig_frame_id = NULL; 00782 } 00783 _orig_width = _width; 00784 _orig_height = _height; 00785 _orig_colorspace = _colorspace; 00786 _header = header; 00787 00788 _image_id = strndup(header->image_id, IMAGE_ID_MAX_LENGTH); 00789 _frame_id = strndup(header->frame_id, FRAME_ID_MAX_LENGTH); 00790 _width = header->width; 00791 _height = header->height; 00792 _colorspace = (colorspace_t)header->colorspace; 00793 } 00794 00795 00796 void 00797 SharedMemoryImageBufferHeader::reset() 00798 { 00799 if ( NULL != _image_id ) { 00800 free(_image_id); 00801 _image_id = NULL; 00802 } 00803 if ( _orig_image_id != NULL ) { 00804 _image_id = strdup(_orig_image_id); 00805 } 00806 if ( NULL != _frame_id ) { 00807 free(_frame_id); 00808 _frame_id = NULL; 00809 } 00810 if ( _orig_frame_id != NULL ) { 00811 _frame_id = strdup(_orig_frame_id); 00812 } 00813 _width =_orig_width; 00814 _height =_orig_height; 00815 _colorspace =_orig_colorspace; 00816 _header = NULL; 00817 } 00818 00819 00820 /** Get colorspace. 00821 * @return colorspace 00822 */ 00823 colorspace_t 00824 SharedMemoryImageBufferHeader::colorspace() const 00825 { 00826 if ( _header) return (colorspace_t)_header->colorspace; 00827 else return _colorspace; 00828 } 00829 00830 00831 /** Get width. 00832 * @return image width 00833 */ 00834 unsigned int 00835 SharedMemoryImageBufferHeader::width() const 00836 { 00837 if ( _header) return _header->width; 00838 else return _width; 00839 } 00840 00841 00842 /** Get height. 00843 * @return image height 00844 */ 00845 unsigned int 00846 SharedMemoryImageBufferHeader::height() const 00847 { 00848 if ( _header) return _header->height; 00849 else return _height; 00850 } 00851 00852 00853 /** Get image number 00854 * @return image number 00855 */ 00856 const char * 00857 SharedMemoryImageBufferHeader::image_id() const 00858 { 00859 return _image_id; 00860 } 00861 00862 00863 /** Get frame ID. 00864 * @return reference coordinate frame ID. 00865 */ 00866 const char * 00867 SharedMemoryImageBufferHeader::frame_id() const 00868 { 00869 return _frame_id; 00870 } 00871 00872 00873 /** Set image id 00874 * @param image_id image ID 00875 */ 00876 void 00877 SharedMemoryImageBufferHeader::set_image_id(const char *image_id) 00878 { 00879 if ( _image_id != NULL) ::free(_image_id); 00880 _image_id = strdup(image_id); 00881 } 00882 00883 00884 /** Set frame ID. 00885 * @param frame_id frame ID 00886 */ 00887 void 00888 SharedMemoryImageBufferHeader::set_frame_id(const char *frame_id) 00889 { 00890 if ( _frame_id != NULL) ::free(_frame_id); 00891 _frame_id = strdup(frame_id); 00892 } 00893 00894 00895 /** Get raw header. 00896 * @return raw header. 00897 */ 00898 SharedMemoryImageBuffer_header_t * 00899 SharedMemoryImageBufferHeader::raw_header() 00900 { 00901 return _header; 00902 } 00903 00904 00905 /** @class SharedMemoryImageBufferLister <fvutils/ipc/shm_image.h> 00906 * Shared memory image buffer lister. 00907 */ 00908 00909 /** Constructor. */ 00910 SharedMemoryImageBufferLister::SharedMemoryImageBufferLister() 00911 { 00912 } 00913 00914 00915 /** Destructor. */ 00916 SharedMemoryImageBufferLister::~SharedMemoryImageBufferLister() 00917 { 00918 } 00919 00920 00921 void 00922 SharedMemoryImageBufferLister::print_header() 00923 { 00924 cout << endl << cgreen << "FireVision Shared Memory Segments - Images" << cnormal << endl 00925 << "========================================================================================" << endl 00926 << cdarkgray; 00927 printf ("%-20s %-20s %-10s %-10s %-9s %-16s %-5s %-5s %s\n", 00928 "Image ID", "Frame ID", "ShmID", "Semaphore", "Bytes", "Color Space", "Width", "Height", 00929 "State"); 00930 cout << cnormal 00931 << "----------------------------------------------------------------------------------------" << endl; 00932 } 00933 00934 00935 void 00936 SharedMemoryImageBufferLister::print_footer() 00937 { 00938 } 00939 00940 00941 void 00942 SharedMemoryImageBufferLister::print_no_segments() 00943 { 00944 cout << "No FireVision shared memory segments found" << endl; 00945 } 00946 00947 00948 void 00949 SharedMemoryImageBufferLister::print_no_orphaned_segments() 00950 { 00951 cout << "No orphaned FireVision shared memory segments found" << endl; 00952 } 00953 00954 00955 void 00956 SharedMemoryImageBufferLister::print_info(const SharedMemoryHeader *header, 00957 int shm_id, int semaphore, 00958 unsigned int mem_size, 00959 const void *memptr) 00960 { 00961 00962 SharedMemoryImageBufferHeader *h = (SharedMemoryImageBufferHeader *)header; 00963 00964 const char *colorspace = colorspace_to_string(h->colorspace()); 00965 00966 printf("%-20s %-20s %-10d %-10d %-9u %-16s %-5u %-5u %s%s\n", 00967 h->image_id(), h->frame_id(), shm_id, semaphore, mem_size, colorspace, 00968 h->width(), h->height(), 00969 (SharedMemory::is_swapable(shm_id) ? "S" : ""), 00970 (SharedMemory::is_destroyed(shm_id) ? "D" : "") 00971 ); 00972 } 00973 00974 } // end namespace firevision