Fawkes API  Fawkes Development Version
histogram_block.cpp
00001 
00002 /***************************************************************************
00003  *  histogram_block.cpp - Histogram block
00004  *
00005  *  Created: Sat Mar 29 21:01:35 2008
00006  *  Copyright  2008  Daniel Beck
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/statistical/histogram_block.h>
00025 #include <core/exceptions/software.h>
00026 #include <cstring>
00027 
00028 using namespace fawkes;
00029 
00030 namespace firevision {
00031 #if 0 /* just to make Emacs auto-indent happy */
00032 }
00033 #endif
00034 
00035 /** @class HistogramBlock <fvutils/statistical/histogram_block.h>
00036  * This class defines a file block for histograms. Additionally, the very basic routines
00037  * to acccess and manipulate data in the histograms are provided.
00038  * @author Daniel Beck
00039  */
00040 
00041 
00042 /** Constructor.
00043  * @param type the type of the histogram block
00044  * @param object_type the object type this histogram is meant for (e.g, ball)
00045  * @param width the width of the histogram
00046  * @param height the height of the histogram
00047  * @param depth the depth of the histogram
00048  */
00049 HistogramBlock::HistogramBlock(histogram_block_type_t type, hint_t object_type,
00050                                uint16_t width, uint16_t height, uint16_t depth)
00051   : FireVisionDataFileBlock(type, width * height * depth * sizeof(uint32_t), 
00052                             sizeof(histogram_block_header_t))
00053 {
00054   _block_header = (histogram_block_header_t*) _spec_header;
00055   _block_header->width = width;
00056   _block_header->height = height;
00057   _block_header->depth = depth;
00058   _block_header->object_type = object_type;
00059 
00060   _histogram_data = (uint32_t*) _data;
00061 }
00062 
00063 /** Copy constructor.
00064  * @param block another block
00065  */
00066 HistogramBlock::HistogramBlock(FireVisionDataFileBlock* block)
00067   : FireVisionDataFileBlock(block)
00068 {
00069   _block_header = (histogram_block_header_t*) _spec_header;
00070   _histogram_data = (uint32_t*) _data;
00071 }
00072 
00073 /** Destructor. */
00074 HistogramBlock::~HistogramBlock()
00075 {
00076 }
00077 
00078 /** Returns the the width of the histogram.
00079  * @return the width of the histogram
00080  */
00081 uint16_t
00082 HistogramBlock::width() const
00083 {
00084   return _block_header->width;
00085 }
00086 
00087 /** Returns the the height of the histogram.
00088  * @return the height of the histogram
00089  */
00090 uint16_t
00091 HistogramBlock::height() const
00092 {
00093   return _block_header->height;
00094 }
00095 
00096 /** Returns the the depth of the histogram.
00097  * @return the depth of the histogram
00098  */
00099 uint16_t
00100 HistogramBlock::depth() const
00101 {
00102   return _block_header->depth;
00103 }
00104 
00105 /** Returns the type of the object the histogram is associated with.
00106  * @return the object type of the histogram
00107  */
00108 hint_t
00109 HistogramBlock::object_type() const
00110 {
00111   return (hint_t) _block_header->object_type;
00112 }
00113 
00114 /** Set the type of the object the histogram is associated with.
00115  * @param object_type the new type of the object
00116  */
00117 void
00118 HistogramBlock::set_object_type(hint_t object_type)
00119 {
00120   _block_header->object_type = object_type;
00121 }
00122 
00123 /** Directly set the histogram data.
00124  * Note: You are reponsible that the data has the right size and format!
00125  * @param data pointer to the histogram data
00126  */
00127 void
00128 HistogramBlock::set_data(uint32_t* data)
00129 {
00130   memcpy(_data, data, _data_size);
00131 }
00132 
00133 /** Store a value in a certain cell of a 2-dimensional histogram.
00134  * @param x the x-coordinate
00135  * @param y the y-coordinate
00136  * @param val the new value
00137  */
00138 void
00139 HistogramBlock::set_value(uint16_t x, uint16_t y, uint32_t val)
00140 {
00141   if (_block_header->depth != 0)
00142     { throw Exception("Trying to acces a 3-dim histogram with a 2-dim access method"); }
00143 
00144   if (x >= _block_header->width)
00145     { 
00146       throw OutOfBoundsException("Given x value is too large (set_value, 2)", 
00147                                  float(x), 0.0f, float(_block_header->width));
00148     }
00149 
00150   if (y >= _block_header->height)
00151     {
00152       throw OutOfBoundsException("Given y value is too large (set_value, 2)", 
00153                                  float(y), 0.0f, float(_block_header->height));
00154     }
00155 
00156   _histogram_data[y * _block_header->width + x] = val;
00157 }
00158 
00159 /** Store a value in a certain cell of a 3-dimensional histogram.
00160  * @param x the x-coordinate
00161  * @param y the y-coordinate
00162  * @param z the z-coordinate
00163  * @param val the new value
00164  */
00165 void
00166 HistogramBlock::set_value(uint16_t x, uint16_t y, uint16_t z, uint32_t val)
00167 {
00168   if ( x >= _block_header->width)
00169     {
00170       throw OutOfBoundsException("Given x value is too large (set_value, 3)", 
00171                                  float(x), 0.0f, float(_block_header->width));
00172     }
00173 
00174   if ( y >= _block_header->height)
00175     {
00176       throw OutOfBoundsException("Given y value is too large (set_value, 3)", 
00177                                  float(y), 0.0f, float(_block_header->height));
00178     }
00179 
00180   if ( z >= _block_header->depth)
00181     {
00182       throw OutOfBoundsException("Given z value is too large (set_value, 3)", 
00183                                  float(z), 0.0f, float(_block_header->depth));
00184     }
00185 
00186   _histogram_data[z * _block_header->width * _block_header->height + y * _block_header->width + x] = val;
00187 }
00188 
00189 /** Obtain a certain value from a 2-dimensional histogram.
00190  * @param x the x-coordinate
00191  * @param y the y-coordinate
00192  * @return the histogram value
00193  */
00194 uint32_t
00195 HistogramBlock::get_value(uint16_t x, uint16_t y)
00196 {
00197   if (_block_header->depth != 0)
00198     { throw Exception("Trying to acces a 3-dim histogram with a 2-dim access method"); }
00199 
00200   if ( x >= _block_header->width)
00201     {
00202       throw OutOfBoundsException("Given x value is too large (get_value, 2)", 
00203                                  float(x), 0.0f, float(_block_header->width));
00204     }
00205 
00206   if ( y >= _block_header->height)
00207     {
00208       throw OutOfBoundsException("Given y value is too large (get_value, 2)", 
00209                                  float(y), 0.0f, float(_block_header->height));
00210     }
00211 
00212   return _histogram_data[y * _block_header->width + x];
00213 }
00214 
00215 /** Obtain a certain value from a 3-dimensional histogram.
00216  * @param x the x-coordinate
00217  * @param y the y-coordinate
00218  * @param z the z-coordinate
00219  * @return the histogram value
00220  */
00221 uint32_t
00222 HistogramBlock::get_value(uint16_t x, uint16_t y, uint16_t z)
00223 {
00224   if ( x >= _block_header->width)
00225     {
00226       throw OutOfBoundsException("Given x value is too large (get_value, 3)", 
00227                                  float(x), 0.0f, _block_header->width - 1);
00228     }
00229 
00230   if ( y >= _block_header->height)
00231     {
00232       throw OutOfBoundsException("Given y value is too large (get_value, 3)", 
00233                                  float(y), 0.0f, _block_header->height - 1);
00234     }
00235 
00236   if ( z >= _block_header->depth)
00237     {
00238       throw OutOfBoundsException("Given z value is too large (get_value, 3)", 
00239                                  float(z), 0.0f, _block_header->depth - 1);
00240     }
00241 
00242   return _histogram_data[z * _block_header->width * _block_header->height + y * _block_header->width + x];
00243 }
00244 
00245 /** Reset the histogram. */
00246 void
00247 HistogramBlock::reset()
00248 {
00249   memset(_histogram_data, 0, _data_size);
00250 }
00251 
00252 } // end namespace firevision