filter.cpp

00001
00002 /***************************************************************************
00003  *  filter.cpp - Abstract class defining a filter
00004  *
00005  *  Created: Mon May 19 15:47:44 2007
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 <filters/filter.h>
00025
00026 #include <core/exceptions/software.h>
00027 #include <cstdlib>
00028 #include <cstring>
00029
00030 using namespace fawkes;
00031 
00032 /** @class Filter <filters/filter.h>
00033  * Filter interface.
00034  * This class defines the general interface that filters are used with.
00035  *
00036  * @author Tim Niemueller
00037  *
00038  * @fn void Filter::apply() = 0
00039  * Apply the filter.
00040  * Apply the filter to the given source and destination
00041  * buffers with given width and height and orientation
00042  * (ori may be ignored for some filters).
00043  */
00044 
00045 /** Constructor.
00046  * @param name name of the filter
00047  * @param max_num_buffers The maximum number of source buffers that can be set.
00048  */
00049 Filter::Filter(const char *name, unsigned int max_num_buffers)
00050 {
00051   if ( max_num_buffers == 0 ) {
00052     throw OutOfBoundsException("Need to set at least one buffer", 0, 1, 0xFFFFFFFF);
00053   }
00054
00055   _name = strdup(name);
00056   _max_num_buffers = max_num_buffers;
00057
00058   src = (unsigned char **)malloc(_max_num_buffers * sizeof(unsigned char *));
00059   memset(src, 0, _max_num_buffers * sizeof(unsigned char *));
00060
00061   src_roi = (ROI **)malloc(_max_num_buffers * sizeof(ROI *));
00062   memset(src_roi, 0, _max_num_buffers * sizeof(ROI *));
00063
00064   ori = (orientation_t *)malloc(_max_num_buffers * sizeof(orientation_t));
00065   memset(ori, 0, _max_num_buffers * sizeof(orientation_t));
00066 }
00067
00068 
00069 /** Destructor. */
00070 Filter::~Filter()
00071 {
00072   free(_name);
00073   free(src);
00074   free(src_roi);
00075   free(ori);
00076 }
00077 
00078 /** Set source buffer with orientation.
00079  * @param buf Buffer to use as source image
00080  * @param roi Region Of Interest to work on
00081  * @param ori Orientation to apply the filter in, maybe ignored
00082  *            in some filters
00083  * @param buffer_num source buffer to set for filter that need
00084  *                   multiple src buffers
00085  * @exception OutOfBoundsException Thrown if buffer_num is illegal
00086  */
00087 void
00088 Filter::set_src_buffer(unsigned char *buf,
00089                        ROI *roi,
00090                        orientation_t ori,
00091                        unsigned int buffer_num)
00092 {
00093   if ( buffer_num >= _max_num_buffers ) {
00094     throw OutOfBoundsException("Invalid buffer number", buffer_num, 0, _max_num_buffers);
00095   }
00096
00097   src[buffer_num]       = buf;
00098   src_roi[buffer_num]   = roi;
00099   this->ori[buffer_num] = ori;
00100 }
00101
00102 
00103 /** Set source buffer.
00104  * @param buf Buffer to use as source image
00105  * @param roi Region Of Interest to work on
00106  * @param buffer_num source buffer to set for filter that need multiple src buffers
00107  * @exception OutOfBoundsException Thrown if buffer_num is illegal
00108  */
00109 void
00110 Filter::set_src_buffer(unsigned char *buf,
00111                        ROI *roi,
00112                        unsigned int buffer_num)
00113 {
00114   if ( buffer_num >= _max_num_buffers ) {
00115     throw OutOfBoundsException("Invalid buffer number", buffer_num, 0, _max_num_buffers);
00116   }
00117
00118   src[buffer_num]     = buf;
00119   src_roi[buffer_num] = roi;
00120   ori[buffer_num]     = ORI_HORIZONTAL;
00121 }
00122
00123 
00124 /** Set the destination buffer.
00125  * @param buf Buffer to use as destination image
00126  * @param roi Region Of Interest where the result is put in the dst image
00127  */
00128 void
00129 Filter::set_dst_buffer(unsigned char *buf, ROI *roi)
00130 {
00131   dst     = buf;
00132   dst_roi = roi;
00133 }
00134
00135 
00136 /** Set the orientation to apply the filter in.
00137  * Maybe ignored by some filters.
00138  * @param ori Orientation
00139  * @param buffer_num buffer this orientation applies to
00140  */
00141 void
00142 Filter::set_orientation(orientation_t ori, unsigned int buffer_num)
00143 {
00144   if ( buffer_num >= _max_num_buffers ) {
00145     throw OutOfBoundsException("Invalid buffer number", buffer_num, 0, _max_num_buffers);
00146   }
00147
00148   this->ori[buffer_num] = ORI_HORIZONTAL;
00149 }
00150
00151 
00152 /** Get filter name
00153  * @return filter name
00154  */
00155 const char *
00156 Filter::name()
00157 {
00158   return _name;
00159 }
00160
00161 
00162 /** This shrinks the regions as needed for a N x N matrix.
00163  * @param r ROI to shrink
00164  * @param n size of the matrix
00165  */
00166 void
00167 Filter::shrink_region(ROI *r, unsigned int n)
00168 {
00169   if (r->start.x < (n/2)) {
00170     r->start.x = n/2;
00171   }
00172   if (r->start.y < (n/2)) {
00173     r->start.y = n/2;
00174   }
00175   if ( (r->start.x + r->width) >= (r->image_width - (n/2)) ) {
00176     r->width -= (r->start.x + r->width) - (r->image_width - (n/2));
00177   }
00178   if ( (r->start.y + r->height) >= (r->image_height - (n/2)) ) {
00179     r->height -= (r->start.y + r->height) - (r->image_height - (n/2));
00180   }
00181 }