Fawkes API  Fawkes Development Version
shm_lut.cpp
00001 
00002 /***************************************************************************
00003  *  shm_lut.cpp - shared memory lookup table
00004  *
00005  *  Generated: Thu feb 09 17:32:31 2006
00006  *  Copyright  2005-2007  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 <fvutils/ipc/shm_lut.h>
00025 #include <fvutils/ipc/shm_exceptions.h>
00026 #include <utils/system/console_colors.h>
00027 
00028 #include <iostream>
00029 #include <cstring>
00030 #include <cstdlib>
00031 #include <cstdio>
00032 
00033 using namespace std;
00034 using namespace fawkes;
00035 
00036 namespace firevision {
00037 #if 0 /* just to make Emacs auto-indent happy */
00038 }
00039 #endif
00040 
00041 /** @class SharedMemoryLookupTable <fvutils/ipc/shm_lut.h>
00042  * Shared memory lookup table.
00043  */
00044 
00045 /** Write Constructor.
00046  * Create a new shared memory segment. Will open a shared memory segment that
00047  * exactly fits the given information. Will throw an error if image with num
00048  * image_num exists it will throw an exception an exception.
00049  * I will create a new segment if no matching segment was found.
00050  * The segment is accessed in read-write mode.
00051  *
00052  * @param lut_id LUT ID
00053  * @param width LUT width
00054  * @param height LUT height
00055  * @param depth LUT depth
00056  * @param bytes_per_cell LUT bytes per cell
00057  */
00058 SharedMemoryLookupTable::SharedMemoryLookupTable(const char *lut_id,
00059                                                  unsigned int width,
00060                                                  unsigned int height,
00061                                                  unsigned int depth,
00062                                                  unsigned int bytes_per_cell)
00063   : SharedMemory(FIREVISION_SHM_LUT_MAGIC_TOKEN, false, true, true)
00064 {
00065   constructor(lut_id, width, height, depth, bytes_per_cell, false);
00066 }
00067 
00068 /** Read constructor.
00069  * This constructor is used to search for an existing shared memory segment.
00070  * It will throw an error if it cannot find a segment with the specified data.
00071  * The segment is opened read-only by default, but this can be overridden with
00072  * the is_read_only argument if needed.
00073  *
00074  * @param lut_id LUT ID
00075  * @param is_read_only true to open read-only
00076  */
00077 SharedMemoryLookupTable::SharedMemoryLookupTable(const char *lut_id,
00078                                                  bool is_read_only)
00079   : SharedMemory(FIREVISION_SHM_LUT_MAGIC_TOKEN, is_read_only, false, false)
00080 {
00081   constructor(lut_id, 0, 0, 0, 0, is_read_only);
00082 }
00083 
00084 
00085 void
00086 SharedMemoryLookupTable::constructor(const char *lut_id,
00087                                      unsigned int width, unsigned int height,
00088                                      unsigned int depth,
00089                                      unsigned int bytes_per_cell,
00090                                      bool is_read_only)
00091 {
00092   _is_read_only    = is_read_only;
00093   __lut_id         = strdup(lut_id);
00094   __width          = width;
00095   __height         = height;
00096   __depth          = depth;
00097   __bytes_per_cell = bytes_per_cell;
00098 
00099   __priv_header = new SharedMemoryLookupTableHeader(__lut_id, __width, __height, __depth, __bytes_per_cell);
00100   _header = __priv_header;
00101   attach();
00102   __raw_header = __priv_header->raw_header();
00103 
00104   if (_memptr == NULL) {
00105     throw Exception("Could not create shared memory segment");
00106   }
00107 }
00108 
00109 
00110 /** Destructor. */
00111 SharedMemoryLookupTable::~SharedMemoryLookupTable()
00112 {
00113   delete __priv_header;
00114   ::free(__lut_id);
00115 }
00116 
00117 
00118 /** Get LUT ID.
00119  * @return LUT ID
00120  */
00121 const char *
00122 SharedMemoryLookupTable::lut_id() const
00123 {
00124   return __lut_id;
00125 }
00126 
00127 
00128 /** Set LUT ID.
00129  * @param lut_id LUT ID
00130  * @return true on success
00131  */
00132 bool
00133 SharedMemoryLookupTable::set_lut_id(const char *lut_id)
00134 {
00135   free();
00136   ::free(__lut_id);
00137   __lut_id = strdup(lut_id);
00138   __priv_header->set_lut_id(__lut_id);
00139   attach();
00140   return (_memptr != NULL);
00141 }
00142 
00143 
00144 /** Get LUT buffer.
00145  * @return LUT buffer
00146  */
00147 unsigned char *
00148 SharedMemoryLookupTable::buffer() const
00149 {
00150   return (unsigned char *)_memptr;
00151 }
00152 
00153 
00154 /** Get LUT width.
00155  * @return LUT width
00156  */
00157 unsigned int
00158 SharedMemoryLookupTable::width() const
00159 {
00160   return __raw_header->width;
00161 }
00162 
00163 
00164 /** Get LUT height.
00165  * @return LUT height
00166  */
00167 unsigned int
00168 SharedMemoryLookupTable::height() const
00169 {
00170   return __raw_header->height;
00171 }
00172 
00173 
00174 /** Get LUT depth.
00175  * @return LUT depth
00176  */
00177 unsigned int
00178 SharedMemoryLookupTable::depth() const
00179 {
00180   return __raw_header->depth;
00181 }
00182 
00183 
00184 /** Get bytes per cell.
00185  * @return bytes per cell
00186  */
00187 unsigned int
00188 SharedMemoryLookupTable::bytes_per_cell() const
00189 {
00190   return __raw_header->bytes_per_cell;
00191 }
00192 
00193 
00194 /** List shared memory LUT segments. */
00195 void
00196 SharedMemoryLookupTable::list()
00197 {
00198   SharedMemoryLookupTableLister *lister = new SharedMemoryLookupTableLister();
00199   SharedMemoryLookupTableHeader *h      = new SharedMemoryLookupTableHeader();
00200 
00201   SharedMemory::list(FIREVISION_SHM_LUT_MAGIC_TOKEN, h, lister);
00202 
00203   delete lister;
00204   delete h;
00205 }
00206 
00207 
00208 /** Erase all shared memory segments that contain FireVision LUTs.
00209  * @param use_lister if true a lister is used to print the shared memory segments
00210  * to stdout while cleaning up.
00211  */
00212 void
00213 SharedMemoryLookupTable::cleanup(bool use_lister)
00214 {
00215   SharedMemoryLookupTableLister *lister = NULL;
00216   SharedMemoryLookupTableHeader *h      = new SharedMemoryLookupTableHeader();
00217 
00218   if ( use_lister ) {
00219     lister = new SharedMemoryLookupTableLister();
00220   }
00221 
00222   SharedMemory::erase_orphaned(FIREVISION_SHM_LUT_MAGIC_TOKEN, h, lister);
00223 
00224   delete lister;
00225   delete h;
00226 }
00227 
00228 
00229 /** Check LUT availability.
00230  * @param lut_id image number to check
00231  * @return true if shared memory segment with requested LUT exists
00232  */
00233 bool
00234 SharedMemoryLookupTable::exists(const char *lut_id)
00235 {
00236   SharedMemoryLookupTableHeader *h = new SharedMemoryLookupTableHeader(lut_id, 0, 0, 0, 0);
00237   bool ex = SharedMemory::exists(FIREVISION_SHM_LUT_MAGIC_TOKEN, h);
00238   delete h;
00239   return ex;
00240 }
00241 
00242 
00243 /** Erase a specific shared memory segment that contains a LUT.
00244  * @param lut_id LUT ID
00245  */
00246 void
00247 SharedMemoryLookupTable::wipe(const char *lut_id)
00248 {
00249   SharedMemoryLookupTableHeader *h = new SharedMemoryLookupTableHeader(lut_id, 0, 0, 0, 0);
00250   SharedMemory::erase(FIREVISION_SHM_LUT_MAGIC_TOKEN, h, NULL);
00251   delete h;
00252 }
00253 
00254 
00255 
00256 /** @class SharedMemoryLookupTableHeader <fvutils/ipc/shm_lut.h>
00257  * Shared memory lookup table header.
00258  */
00259 
00260 /** Constructor. */
00261 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader()
00262 {
00263   __lut_id = NULL;
00264   __width = 0;
00265   __height = 0;
00266   __depth = 0;
00267   __bytes_per_cell = 0;
00268   __header = NULL;
00269 }
00270 
00271 
00272 /** Constructor.
00273  * @param lut_id LUT ID
00274  * @param width LUT width
00275  * @param height LUT height
00276  * @param bytes_per_cell bytes per cell
00277  */
00278 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader(const char *lut_id,
00279                                                              unsigned int width,
00280                                                              unsigned int height,
00281                                                              unsigned int bytes_per_cell)
00282 {
00283   __lut_id = strdup(lut_id);
00284   __width  = width;
00285   __height = height;
00286   __bytes_per_cell = bytes_per_cell;
00287 
00288   __header = NULL;
00289 }
00290 
00291 
00292 /** Constructor.
00293  * @param lut_id LUT ID
00294  * @param width LUT width
00295  * @param height LUT height
00296  * @param depth LUT depth
00297  * @param bytes_per_cell bytes per cell
00298  */
00299 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader(const char *lut_id,
00300                                                              unsigned int width,
00301                                                              unsigned int height,
00302                                                              unsigned int depth,
00303                                                              unsigned int bytes_per_cell)
00304 {
00305   __lut_id = strdup(lut_id);
00306   __width  = width;
00307   __height = height;
00308   __depth  = depth;
00309   __bytes_per_cell = bytes_per_cell;
00310 
00311   __header = NULL;
00312 }
00313 
00314 
00315 /** Copy constructor.
00316  * @param h header to copy data from
00317  */
00318 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader(const SharedMemoryLookupTableHeader *h)
00319 {
00320   if( h->__lut_id != NULL ) {
00321     __lut_id = strdup(h->__lut_id);
00322   } else {
00323     __lut_id = NULL;
00324   }
00325   __width  = h->__width;
00326   __height = h->__height;
00327   __depth  = h->__depth;
00328   __bytes_per_cell = h->__bytes_per_cell;
00329 
00330   __header = NULL;
00331 }
00332 
00333 
00334 /** Destructor. */
00335 SharedMemoryLookupTableHeader::~SharedMemoryLookupTableHeader()
00336 {
00337   __header = NULL;
00338   if ( __lut_id != NULL ) {
00339     free(__lut_id);
00340     __lut_id = NULL;
00341   }
00342 }
00343 
00344 
00345 SharedMemoryHeader *
00346 SharedMemoryLookupTableHeader::clone() const
00347 {
00348   return new SharedMemoryLookupTableHeader(this);
00349 }
00350 
00351 
00352 size_t
00353 SharedMemoryLookupTableHeader::size()
00354 {
00355   return sizeof(SharedMemoryLookupTable_header_t);
00356 }
00357 
00358 
00359 size_t
00360 SharedMemoryLookupTableHeader::data_size()
00361 {
00362   if (__header == NULL) {
00363     return __width * __height * __depth * __bytes_per_cell;
00364   } else {
00365     return __header->width * __header->height * __header->depth * __header->bytes_per_cell;
00366   }
00367 }
00368 
00369 
00370 bool
00371 SharedMemoryLookupTableHeader::matches(void *memptr)
00372 {
00373   SharedMemoryLookupTable_header_t *h = (SharedMemoryLookupTable_header_t *)memptr;
00374 
00375   if (__lut_id == NULL) {
00376     return true;
00377 
00378   } else if (strncmp(h->lut_id, __lut_id, LUT_ID_MAX_LENGTH) == 0) {
00379 
00380     if ( (__width == 0) ||
00381          (__height == 0) ||
00382          (__depth == 0) ||
00383          (__bytes_per_cell == 0) ||
00384          ( (h->width == __width) &&
00385            (h->height == __height) &&
00386            (h->depth == __depth) &&
00387            (h->bytes_per_cell == __bytes_per_cell) )
00388          ) {
00389       return true;
00390     } else {
00391       throw InconsistentLUTException("Inconsistent lookup table found in memory (meta)");
00392     }
00393   } else {
00394     return false;
00395   }
00396 
00397 }
00398 
00399 
00400 /** Print Info. */
00401 void
00402 SharedMemoryLookupTableHeader::print_info()
00403 {
00404   if (__header == NULL) {
00405     cout << "No image set" << endl;
00406     return;
00407   }
00408   cout << "SharedMemory Lookup Table Info: " << endl
00409        << "    LUT ID:         " << __header->lut_id << endl
00410        << "    dimensions:     " << __header->width << "x" << __header->height << "x" 
00411        << __header->depth << endl
00412        << "    bytes per cell: " << __header->bytes_per_cell << endl;
00413 }
00414 
00415 
00416 /** Check if buffer should be created.
00417  * @return true, if width, height and bytes per cell are all greater than
00418  * zero.
00419  */
00420 bool
00421 SharedMemoryLookupTableHeader::create()
00422 {
00423   return ( (__width > 0) &&
00424            (__height > 0) &&
00425            (__depth > 0) &&
00426            (__bytes_per_cell > 0) );
00427 }
00428 
00429 
00430 void
00431 SharedMemoryLookupTableHeader::initialize(void *memptr)
00432 {
00433   __header = (SharedMemoryLookupTable_header_t *)memptr;
00434   memset(memptr, 0, sizeof(SharedMemoryLookupTable_header_t));
00435          
00436   strncpy(__header->lut_id, __lut_id, LUT_ID_MAX_LENGTH);
00437   __header->width          = __width;
00438   __header->height         = __height;
00439   __header->depth          = __depth;
00440   __header->bytes_per_cell = __bytes_per_cell;
00441 }
00442 
00443 
00444 void
00445 SharedMemoryLookupTableHeader::set(void *memptr)
00446 {
00447   __header = (SharedMemoryLookupTable_header_t *)memptr;
00448 }
00449 
00450 
00451 void
00452 SharedMemoryLookupTableHeader::reset()
00453 {
00454   __header = NULL;
00455 }
00456 
00457 
00458 /** Check for equality of headers.
00459  * First checks if passed SharedMemoryHeader is an instance of
00460  * SharedMemoryLookupTableHeader. If not returns false, otherwise it compares
00461  * LUT ID, width, height, depth and bytes per cell. If all match returns true,
00462  * false if any of them differs.
00463  * @param s shared memory header to compare to
00464  * @return true if the two instances identify the very same shared memory segments,
00465  * false otherwise
00466  */
00467 bool
00468 SharedMemoryLookupTableHeader::operator==(const SharedMemoryHeader &s) const
00469 {
00470   const SharedMemoryLookupTableHeader *h = dynamic_cast<const SharedMemoryLookupTableHeader *>(&s);
00471   if ( ! h ) {
00472     return false;
00473   } else {
00474     return ( (strncmp(__lut_id, h->__lut_id, LUT_ID_MAX_LENGTH) == 0) &&
00475              (__width == h->__width) &&
00476              (__height == h->__height) &&
00477              (__depth == h->__depth) &&
00478              (__bytes_per_cell == h->__bytes_per_cell) );
00479   }
00480 }
00481 
00482 
00483 /** Get LUT width.
00484  * @return LUT width.
00485  */
00486 unsigned int
00487 SharedMemoryLookupTableHeader::width() const
00488 {
00489   if (__header == NULL) return 0;
00490   return __header->width;
00491 }
00492 
00493 
00494 /** Get LUT height.
00495  * @return LUT height.
00496  */
00497 unsigned int
00498 SharedMemoryLookupTableHeader::height() const
00499 {
00500   if (__header == NULL) return 0;
00501   return __header->height;
00502 }
00503 
00504 
00505 /** Get LUT depth.
00506  * @return LUT depth.
00507  */
00508 unsigned int
00509 SharedMemoryLookupTableHeader::depth() const
00510 {
00511   if (__header == NULL) return 0;
00512   return __header->depth;
00513 }
00514 
00515 
00516 /** Get bytes per cell.
00517  * @return bytes per cell.
00518  */
00519 unsigned int
00520 SharedMemoryLookupTableHeader::bytes_per_cell() const
00521 {
00522   if (__header == NULL) return 0;
00523   return __header->bytes_per_cell;
00524 }
00525 
00526 
00527 /** Get LUT ID.
00528  * @return LUT Id
00529  */
00530 const char *
00531 SharedMemoryLookupTableHeader::lut_id() const
00532 {
00533   if (__header == NULL) return NULL;
00534   return __header->lut_id;
00535 }
00536 
00537 
00538 /** Set LUT ID.
00539  * @param lut_id LUT ID
00540  */
00541 void
00542 SharedMemoryLookupTableHeader::set_lut_id(const char *lut_id)
00543 {
00544   if ( __lut_id )  free(__lut_id);
00545   __lut_id = strdup(lut_id);
00546 }
00547 
00548 
00549 /** Get raw header.
00550  * @return raw header.
00551  */
00552 SharedMemoryLookupTable_header_t *
00553 SharedMemoryLookupTableHeader::raw_header()
00554 {
00555   return __header;
00556 }
00557 
00558 /** @class SharedMemoryLookupTableLister <fvutils/ipc/shm_lut.h>
00559  * Shared memory lookup table lister.
00560  */
00561 
00562 
00563 /** Constructor. */
00564 SharedMemoryLookupTableLister::SharedMemoryLookupTableLister()
00565 {
00566 }
00567 
00568 
00569 /** Destructor. */
00570 SharedMemoryLookupTableLister::~SharedMemoryLookupTableLister()
00571 {
00572 }
00573 
00574 
00575 void
00576 SharedMemoryLookupTableLister::print_header()
00577 {
00578   cout << endl << cgreen << "FireVision Shared Memory Segments - Lookup Tables"
00579        << cnormal << endl
00580        << "========================================================================================" << endl
00581        << cdarkgray;
00582   printf ("%-23s %-10s %-10s %-10s %-9s %-9s %-9s\n",
00583           "LUT ID", "ShmID", "Semaphore", "Bytes", "Width", "Height", "State");
00584   cout << cnormal
00585        << "----------------------------------------------------------------------------------------" << endl;
00586 }
00587 
00588 
00589 void
00590 SharedMemoryLookupTableLister::print_footer()
00591 {
00592 }
00593 
00594 
00595 void
00596 SharedMemoryLookupTableLister::print_no_segments()
00597 {
00598   cout << "No FireVision shared memory segments containing lookup tables found" << endl;
00599 }
00600 
00601 
00602 
00603 
00604 void
00605 SharedMemoryLookupTableLister::print_no_orphaned_segments()
00606 {
00607   cout << "No orphaned FireVision shared memory segments containing lookup tables found" << endl;
00608 }
00609 
00610 void
00611 SharedMemoryLookupTableLister::print_info(const SharedMemoryHeader *header,
00612                                           int shm_id, int semaphore,
00613                                           unsigned int mem_size,
00614                                           const void *memptr)
00615 {
00616 
00617   SharedMemoryLookupTableHeader *h = (SharedMemoryLookupTableHeader *)header;
00618 
00619   printf("%-23s %-10d %-10d %-10u %-9u %-9u %s%s\n",
00620          h->lut_id(), shm_id, semaphore, mem_size,
00621          h->width(), h->height(),
00622          (SharedMemory::is_swapable(shm_id) ? "S" : ""),
00623          (SharedMemory::is_destroyed(shm_id) ? "D" : "")
00624          );
00625 }
00626 
00627 } // end namespace firevision