00001 /* --------------------------------------------------------------------------- 00002 Phission : 00003 Realtime Vision Processing System 00004 00005 Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu) 00006 University of Massachusetts at Lowell, 00007 Laboratory for Artificial Intelligence and Robotics 00008 00009 This file is part of Phission. 00010 00011 Phission is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU Lesser General Public License as published by 00013 the Free Software Foundation; either version 2 of the License, or 00014 (at your option) any later version. 00015 00016 Phission 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 Lesser General Public License for more details. 00020 00021 You should have received a copy of the GNU Lesser General Public License 00022 along with Phission; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 00025 ---------------------------------------------------------------------------*/ 00026 #ifdef HAVE_CONFIG_H 00027 #include <phissionconfig.h> 00028 #endif 00029 00030 #include <phStandard.h> 00031 00032 #include <phObject.h> 00033 #include <phMutex.h> 00034 #include <phSemaphore.h> 00035 #include <phCondition.h> 00036 #include <phRWLock.h> 00037 #include <phThread.h> 00038 #include <phList.h> 00039 #include <phTimeStamp.h> 00040 #include <phTimeInterval.h> 00041 #include <phLiveObject.h> 00042 #include <phDataObject.h> 00043 #include <phImage.h> 00044 00045 #include <phFilter.h> 00046 00047 #include <phError.h> 00048 #include <phMemory.h> 00049 #include <phPrint.h> 00050 00051 /* ------------------------------------------------------------------------ */ 00052 phFilter::phFilter(const char *name) 00053 { 00054 phFUNCTION("phFilter::phFilter") 00055 int locked = 0; 00056 00057 phTHIS_LOOSE_LOCK(locked); 00058 00059 this->setName(name); 00060 00061 this->m_workspaceImage = NULL; 00062 this->m_originalImage = NULL; 00063 this->m_format = phImageValidFormatMask; 00064 00065 /* set before 'filter()' is called */ 00066 this->format = 0; 00067 this->depth = 0; 00068 this->height = 0; 00069 this->width = 0; 00070 this->Image = NULL; 00071 00072 this->m_monitorSource = NULL; 00073 00074 this->m_filterEnabled = 1; 00075 00076 phTHIS_LOOSE_UNLOCK(locked); 00077 } 00078 /* ------------------------------------------------------------------------ */ 00079 phFilter::~phFilter() 00080 { 00081 } 00082 00083 /* ------------------------------------------------------------------------ */ 00084 uint32_t phFilter::queryFormat() 00085 { 00086 return this->m_format; 00087 } 00088 /* ------------------------------------------------------------------------ */ 00089 int phFilter::verifyFormat(uint32_t format) 00090 { 00091 phFUNCTION("phFilter::verifyFormat") 00092 int valrc = 0; 00093 int locked = 0; 00094 00095 phTHIS_LOOSE_LOCK(locked); 00096 00097 valrc = (format & this->m_format) ? phSUCCESS : phFAIL; 00098 00099 phTHIS_LOOSE_UNLOCK(locked); 00100 00101 return valrc; 00102 } 00103 00104 /* ------------------------------------------------------------------------ */ 00105 int phFilter::setWorkspace( phImage *workspaceImage ) 00106 { 00107 phFUNCTION("phFilter::setWorkspace") 00108 int locked = 0; 00109 00110 phTHIS_LOOSE_LOCK(locked); 00111 00112 this->m_workspaceImage = workspaceImage; 00113 if (this->m_workspaceImage == NULL) 00114 { 00115 this->Image = NULL; 00116 } 00117 else 00118 { 00119 this->Image = (uint8_t *)m_workspaceImage->getImage(); 00120 } 00121 00122 phTHIS_LOOSE_UNLOCK(locked); 00123 00124 return phSUCCESS; 00125 } 00126 00127 /* ------------------------------------------------------------------------ */ 00128 int phFilter::setOriginal( phImage *originalImage ) 00129 { 00130 phFUNCTION("phFilter::setOriginal") 00131 int locked = 0; 00132 00133 phTHIS_LOOSE_LOCK(locked); 00134 00135 this->m_originalImage = originalImage; 00136 if (this->m_originalImage == NULL) 00137 { 00138 this->OriginalImage = NULL; 00139 } 00140 else 00141 { 00142 this->OriginalImage = (uint8_t *)m_originalImage->getImage(); 00143 } 00144 00145 phTHIS_LOOSE_UNLOCK(locked); 00146 00147 return phSUCCESS; 00148 } 00149 00150 /* ------------------------------------------------------------------------ */ 00151 int phFilter::resetImage() 00152 { 00153 phFUNCTION("phFilter::resetImage") 00154 int locked = 0; 00155 00156 phTHIS_LOOSE_LOCK(locked); 00157 00158 if (this->m_originalImage != NULL) 00159 { 00160 rc = this->m_workspaceImage->setImage(*(this->m_originalImage)); 00161 phCHECK_RC(rc,NULL,"this[%s]->m_workspaceImage.setImage failed.", 00162 this->getName()); 00163 00164 rc = this->setFilterVars(); 00165 phCHECK_RC(rc,NULL,"this[%s]->setFilterVars() failed.", 00166 this->getName()); 00167 } 00168 else 00169 { 00170 goto error; 00171 } 00172 00173 phTHIS_LOOSE_UNLOCK(locked); 00174 00175 return phSUCCESS; 00176 00177 error: 00178 phTHIS_LOOSE_UNLOCK(locked); 00179 00180 return phFAIL; 00181 } 00182 00183 /* ------------------------------------------------------------------------ */ 00184 int phFilter::assignMonitorSource() 00185 { 00186 this->m_monitorSource = this->m_workspaceImage; 00187 00188 return phSUCCESS; 00189 } 00190 00191 /* ------------------------------------------------------------------------ */ 00192 int phFilter::updateMonitorOutput() 00193 { 00194 phFUNCTION("phFilter::updateMonitorOutput") 00195 00196 rc = this->assignMonitorSource(); 00197 00198 if (this->m_monitorSource != NULL) 00199 { 00200 /* Only copy from the source to the output if someone is 00201 * listening */ 00202 if (this->m_monitorOutput.hasClients()) 00203 { 00204 /* The copy is placed into the passed object, not 00205 * into the object whose 'copy' method is being called */ 00206 rc = this->m_monitorSource->copy(&(this->m_monitorOutput)); 00207 phCHECK_RC(rc,NULL,"this[%s]->m_monitorOutput.copy() failed.", 00208 this->getName()); 00209 } 00210 } 00211 00212 return phSUCCESS; 00213 00214 error: 00215 return phFAIL; 00216 } 00217 00218 /* ------------------------------------------------------------------------ */ 00219 int phFilter::enable() 00220 { 00221 phFUNCTION("phFilter::enable") 00222 int locked = 0; 00223 00224 phTHIS_LOOSE_LOCK(locked); 00225 00226 this->m_filterEnabled = 1; 00227 00228 phTHIS_LOOSE_UNLOCK(locked); 00229 00230 return phSUCCESS; 00231 } 00232 00233 /* ------------------------------------------------------------------------ */ 00234 int phFilter::disable() 00235 { 00236 phFUNCTION("phFilter::disable") 00237 int locked = 0; 00238 00239 phTHIS_LOOSE_LOCK(locked); 00240 00241 this->m_filterEnabled = 0; 00242 00243 phTHIS_LOOSE_UNLOCK(locked); 00244 00245 return phSUCCESS; 00246 } 00247 00248 /* ------------------------------------------------------------------------ */ 00249 uint32_t phFilter::isEnabled() 00250 { 00251 return this->m_filterEnabled; 00252 } 00253 00254 /* ------------------------------------------------------------------------ */ 00255 /* Activated/Signaled at the end of the filter from 00256 * the data in the workspace */ 00257 phLiveObject *phFilter::getLiveSourceOutput() 00258 { 00259 return &this->m_monitorOutput; 00260 } 00261 00262 /* ------------------------------------------------------------------------ */ 00263 /* This is what a cloneFilter method would look like. It's commented out here 00264 * because this is a purely virtual function in the base class and must 00265 * be overloaded in the derived class */ 00266 /* ------------------------------------------------------------------------ */ 00267 /* 00268 phFilter *phFilter::cloneFilter() 00269 { 00270 phFUNCTION("phFilter::cloneFilter") 00271 int locked = 0; 00272 00273 phFilter *ret = NULL; 00274 00275 phTHIS_LOOSE_LOCK(locked); 00276 00277 ret = new phFilter(this->getName()); 00278 00279 phTHIS_LOOSE_UNLOCK(locked); 00280 00281 return ret; 00282 } 00283 */ 00284 00285 /* ------------------------------------------------------------------------ */ 00286 /* Sets the values of the variables that are used within 'filter' */ 00287 /* ------------------------------------------------------------------------ */ 00288 int phFilter::setFilterVars() 00289 { 00290 phFUNCTION("phFilter::setFilterVars") 00291 00292 this->Image = (uint8_t *)this->m_workspaceImage->getImage(); 00293 00294 if (this->m_originalImage != NULL) 00295 { 00296 this->OriginalImage = (uint8_t *)this->m_originalImage->getImage(); 00297 } 00298 00299 /* Check to make sure the workspace is a valid pointer */ 00300 phCHECK_NULLPTR(this->Image,NULL,"[%s]Image == NULL",this->getName()); 00301 00302 /* initialize image dimensions and variables */ 00303 this->width = this->m_workspaceImage->getWidth(); 00304 this->height = this->m_workspaceImage->getHeight(); 00305 this->format = this->m_workspaceImage->getFormat(); 00306 00307 this->depth = phImageFormatToDepth(this->format); 00308 00309 return phSUCCESS; 00310 error: 00311 return phFAIL; 00312 } 00313 00314 /* ------------------------------------------------------------------------ */ 00315 int phFilter::process() 00316 { 00317 phFUNCTION("phFilter::process") 00318 int locked = 0; 00319 00320 phTHIS_LOOSE_LOCK(locked); 00321 00322 if (this->m_filterEnabled == 0) goto success; 00323 00324 if (this->m_workspaceImage == NULL) goto error; 00325 00326 /* Setup the input variables for 'filter' */ 00327 rc = this->setFilterVars(); 00328 phCHECK_RC(rc,NULL,"this[%s]->setFilterVars() failed.", 00329 this->getName()); 00330 00331 /* Try to lock the workspace image */ 00332 rc = this->m_workspaceImage->writeLock(); 00333 phCHECK_RC(rc,NULL,"this[%s]->m_workspaceImage->lock() failed.", 00334 this->getName()); 00335 00336 if (this->m_originalImage != NULL) 00337 { 00338 /* Try to lock the original image */ 00339 rc = this->m_originalImage->readLock(); 00340 phCHECK_RC(rc,NULL,"this[%s]->m_originalImage->readLock() failed.", 00341 this->getName()); 00342 } 00343 00344 /* verify the input is of a valid format */ 00345 rc = this->verifyFormat(this->m_workspaceImage->getFormat()); 00346 phCHECK_RC(rc,NULL,"[filter:%s][in_format:%s]\n\tInput image format unsupported by filter.", 00347 this->getName(), 00348 phImageFormatToString(this->m_workspaceImage->getFormat())); 00349 00350 /* Run the user defined filter */ 00351 rc = this->filter(); 00352 phCHECK_RC(rc,NULL,"this[%s]->filter() failed.", 00353 this->getName()); 00354 00355 rc = this->updateMonitorOutput(); 00356 phCHECK_RC(rc,NULL,"this[%s]->updateMonitorOutput() failed.", 00357 this->getName()); 00358 00359 if (this->m_originalImage != NULL) 00360 { 00361 rc = this->m_originalImage->rwUnlock(); 00362 phCHECK_RC(rc,NULL,"this[%s]->m_originalImage->rwUnlock() failed.", 00363 this->getName()); 00364 } 00365 00366 rc = this->m_workspaceImage->rwUnlock(); 00367 phCHECK_RC(rc,NULL,"this[%s]->m_workspaceImage->unlock() failed.", 00368 this->getName()); 00369 00370 success: 00371 phTHIS_LOOSE_UNLOCK(locked); 00372 00373 return phSUCCESS; 00374 error: 00375 if (this->m_originalImage != NULL) 00376 { 00377 rc = this->m_originalImage->rwUnlock(); 00378 phPRINT_RC(rc,NULL,"this[%s]->m_originalImage->rwUnlock()", 00379 this->getName()); 00380 } 00381 00382 if (this->m_workspaceImage != NULL) 00383 { 00384 rc = this->m_workspaceImage->rwUnlock(); 00385 phPRINT_RC(rc,NULL,"this[%s]->m_workspaceImage->rwUnlock()", 00386 this->getName()); 00387 } 00388 00389 phTHIS_LOOSE_UNLOCK(locked); 00390 00391 return phFAIL; 00392 }
Copyright (C) 2002 - 2007 |
Philip D.S. Thoren ( pthoren@users.sourceforge.net ) University Of Massachusetts at Lowell Robotics Lab |