00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "LensDB.h"
00025 #include <boost/filesystem.hpp>
00026 #include <iostream>
00027 #include <hugin_utils/stl_utils.h>
00028
00029
00030
00031 #define MIN_LF_VERSION 0x20501
00032
00033 namespace HuginBase
00034 {
00035
00036 namespace LensDB
00037 {
00038
00039 #if BOOST_FILESYSTEM_VERSION < 3
00040 typedef boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> basic_path;
00041 #define GETPATHSTRING(x) x
00042 #else
00043 typedef boost::filesystem::path basic_path;
00044 #define GETPATHSTRING(x) (x).string()
00045 #endif
00046
00047 LensDB* LensDB::m_instance=NULL;
00048
00049 LensDB::LensDB()
00050 {
00051 m_db=lf_db_new();
00052 if(!m_db)
00053 {
00054 m_db=NULL;
00055 }
00056 else
00057 {
00058 m_user_db_path=std::string(m_db->HomeDataDir);
00059 };
00060 m_initialized=false;
00061 m_lenses=NULL;
00062 m_newDB=NULL;
00063 m_updatedLenses=NULL;
00064 m_currentLens=NULL;
00065 m_updatedMounts=NULL;
00066 m_needLensCleanup=true;
00067 };
00068
00069 LensDB::~LensDB()
00070 {
00071 FreeLensList();
00072 if (m_db!=NULL)
00073 {
00074 m_db->Destroy();
00075 };
00076 CleanSaveInformation();
00077 };
00078
00079 void LensDB::FreeLensList()
00080 {
00081 if(m_lenses!=NULL)
00082 {
00083 if(!m_needLensCleanup)
00084 {
00085 delete [] m_lenses;
00086 }
00087 else
00088 {
00089 lf_free(m_lenses);
00090 };
00091 };
00092 m_lenses=NULL;
00093 };
00094
00095 LensDB& LensDB::GetSingleton()
00096 {
00097 if(m_instance==NULL)
00098 {
00099 m_instance = new LensDB();
00100 };
00101 return *m_instance;
00102 };
00103
00104 void LensDB::Clean()
00105 {
00106 if(m_instance!=NULL)
00107 {
00108 delete m_instance;
00109 };
00110 m_instance=NULL;
00111 };
00112
00113 void LensDB::SetMainDBPath(std::string mainPath)
00114 {
00115 m_main_db_path=mainPath;
00116 };
00117
00118 std::string LensDB::GetMainDBPath()
00119 {
00120 return m_main_db_path;
00121 };
00122
00123 std::string LensDB::GetUserDBPath()
00124 {
00125 return m_user_db_path;
00126 };
00127
00128 bool LensDB::InitDB()
00129 {
00130 if(m_initialized)
00131 return true;
00132 if(m_db!=NULL)
00133 {
00134 #if LF_VERSION < MIN_LF_VERSION
00135
00136 char * old_locale = setlocale(LC_NUMERIC,NULL);
00137 old_locale = strdup(old_locale);
00138 setlocale(LC_NUMERIC,"C");
00139 #endif
00140 if(m_main_db_path.empty())
00141 {
00142 lfError e=m_db->Load();
00143 m_initialized=true;
00144 }
00145 else
00146 {
00147 LoadFilesInDir(m_main_db_path);
00148 LoadFilesInDir(m_user_db_path);
00149 m_initialized=true;
00150 };
00151 #if LF_VERSION < MIN_LF_VERSION
00152
00153 setlocale(LC_NUMERIC,old_locale);
00154 free(old_locale);
00155 #endif
00156 };
00157 return m_initialized;
00158 };
00159
00160
00161 bool LensDB::LoadFilesInDir(std::string path)
00162 {
00163 if(m_db==NULL)
00164 return false;
00165 lfError e=LF_NO_ERROR;
00166 basic_path p(path);
00167 try
00168 {
00169 if(exists(p))
00170 {
00171 if (is_directory(p))
00172 {
00173 typedef std::vector<basic_path> fl_vec;
00174 fl_vec filelist;
00175 std::copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), std::back_inserter(filelist));
00176 for(fl_vec::const_iterator it=filelist.begin();it!=filelist.end();it++)
00177 {
00178 basic_path file=*it;
00179 if(GETPATHSTRING(file.extension())==std::string(".xml"))
00180 {
00181 lfError e2=m_db->Load(file.string().c_str());
00182 if(e==LF_NO_ERROR && e2!=LF_NO_ERROR)
00183 {
00184 e=e2;
00185 };
00186 };
00187 };
00188 }
00189 }
00190 }
00191 catch (const boost::filesystem::filesystem_error& ex)
00192 {
00193 std::cout << "Error reading lensfun db. Code: " << ex.what() << '\n';
00194 }
00195 return e==LF_NO_ERROR;
00196 };
00197
00198 void LensDB::ReloadUserPart()
00199 {
00200 if(m_db==NULL)
00201 {
00202 return;
00203 };
00204 if(!m_initialized)
00205 {
00206 InitDB();
00207 }
00208 else
00209 {
00210 LoadFilesInDir(m_user_db_path);
00211 };
00212 };
00213
00214 bool LensDB::GetCropFactor(std::string maker, std::string model, double &cropFactor)
00215 {
00216 InitDB();
00217 if(!m_initialized)
00218 return false;
00219 cropFactor=0;
00220 const lfCamera **cameras=m_db->FindCameras(maker.c_str(),model.c_str());
00221 if(cameras)
00222 {
00223 cropFactor=cameras[0]->CropFactor;
00224 }
00225 lf_free (cameras);
00226 return cropFactor>0;
00227 };
00228
00229 bool LensDB::GetCameraMount(std::string maker, std::string model, std::string &mount)
00230 {
00231 InitDB();
00232 if(!m_initialized)
00233 return false;
00234 mount="";
00235 const lfCamera **cameras=m_db->FindCameras(maker.c_str(),model.c_str());
00236 if(cameras)
00237 {
00238 mount=std::string(cameras[0]->Mount);
00239 }
00240 lf_free (cameras);
00241 return !mount.empty();
00242 };
00243
00244 bool LensDB::FindLens(std::string camMaker, std::string camModel, std::string lens)
00245 {
00246 FreeLensList();
00247 m_needLensCleanup=true;
00248 InitDB();
00249 if(!m_initialized)
00250 {
00251 return false;
00252 };
00253 if(camMaker.empty() && camModel.empty() && lens.empty())
00254 {
00255 return false;
00256 };
00257 if(lens.empty() || hugin_utils::tolower(lens)=="standard")
00258 {
00259 const lfCamera** cam=m_db->FindCameras(camMaker.c_str(),camModel.c_str());
00260 if(cam)
00261 {
00262 m_lenses=m_db->FindLenses(cam[0],NULL,"Standard");
00263 lf_free(cam);
00264 }
00265 else
00266 {
00267 return false;
00268 };
00269 }
00270 else
00271 {
00272 if(!camModel.empty())
00273 {
00274 const lfCamera** cam=m_db->FindCameras(camMaker.c_str(),camModel.c_str());
00275 if(cam)
00276 {
00277 m_lenses=m_db->FindLenses(cam[0], NULL, lens.c_str());
00278 lf_free(cam);
00279 }
00280 else
00281 {
00282 m_lenses=m_db->FindLenses(NULL, NULL, lens.c_str());
00283 }
00284 }
00285 else
00286 {
00287 m_lenses=m_db->FindLenses(NULL, NULL,lens.c_str());
00288 };
00289 };
00290 if(m_lenses)
00291 {
00292 return true;
00293 }
00294 else
00295 {
00296 lf_free(m_lenses);
00297 m_lenses=NULL;
00298 return false;
00299 };
00300 };
00301
00302 void LensDB::SetActiveLens(const lfLens* activeLens)
00303 {
00304 FreeLensList();
00305 m_needLensCleanup=false;
00306 m_lenses=new const lfLens* [1];
00307 m_lenses[0]=activeLens;
00308 };
00309
00310 bool LensDB::CheckLensFocal(double focal)
00311 {
00312 if(m_lenses==NULL)
00313 {
00314 return false;
00315 };
00316 return focal>=m_lenses[0]->MinFocal && focal<=m_lenses[0]->MaxFocal;
00317 };
00318
00319 bool LensDB::CheckLensAperture(double aperture)
00320 {
00321 if(m_lenses==NULL)
00322 {
00323 return false;
00324 };
00325 if(m_lenses[0]->MinAperture>0)
00326 {
00327 return aperture>=m_lenses[0]->MinAperture;
00328 }
00329 else
00330 {
00331
00332 return true;
00333 };
00334 };
00335
00336 bool LensDB::FindLenses(std::string camMaker, std::string camModel, std::string lensname, LensDBList &foundLenses, bool fuzzy)
00337 {
00338 InitDB();
00339 if(!m_initialized)
00340 {
00341 return false;
00342 };
00343 foundLenses.SetCameraModelMaker(camMaker, camModel);
00344 if(camMaker.empty() && camModel.empty() && lensname.empty())
00345 {
00346 return false;
00347 };
00348 const lfLens **lenses;
00349 int searchFlag=fuzzy ? LF_SEARCH_LOOSE : 0;
00350 if(lensname.empty() || hugin_utils::tolower(lensname)=="standard")
00351 {
00352 const lfCamera** cam=m_db->FindCameras(camMaker.c_str(),camModel.c_str());
00353 if(cam)
00354 {
00355 lenses=m_db->FindLenses(cam[0],NULL,"Standard",searchFlag);
00356 lf_free(cam);
00357 }
00358 else
00359 {
00360 return false;
00361 };
00362 }
00363 else
00364 {
00365 if(!camModel.empty())
00366 {
00367 const lfCamera** cam=m_db->FindCameras(camMaker.c_str(), camModel.c_str());
00368 if(cam)
00369 {
00370 lenses=m_db->FindLenses(cam[0], NULL, lensname.c_str(), searchFlag);
00371 lf_free(cam);
00372 }
00373 else
00374 {
00375 lenses=m_db->FindLenses(NULL, NULL, lensname.c_str(), searchFlag);
00376 }
00377 }
00378 else
00379 {
00380 lenses=m_db->FindLenses(NULL, NULL, lensname.c_str(), searchFlag);
00381 };
00382 };
00383
00384 foundLenses.SetLenses(lenses);
00385 return foundLenses.GetLensCount()>0;
00386 };
00387
00388 bool LensDB::GetMounts(std::vector<std::string> &foundMounts)
00389 {
00390 InitDB();
00391 if(!m_initialized)
00392 {
00393 return false;
00394 };
00395 foundMounts.clear();
00396 const lfMount *const* mounts=m_db->GetMounts();
00397 if(mounts)
00398 {
00399 for(int i=0;mounts[i];i++)
00400 {
00401 foundMounts.push_back(m_db->MountName(mounts[i]->Name));
00402 }
00403 };
00404 return foundMounts.size()>0;
00405 };
00406
00409 bool TranslateProjectionLF2Hugin(const lfLens* lens, BaseSrcPanoImage::Projection & projection)
00410 {
00411 switch(lens->Type)
00412 {
00413 case LF_RECTILINEAR:
00414 projection=BaseSrcPanoImage::RECTILINEAR;
00415 return true;
00416 break;
00417 case LF_FISHEYE:
00418 projection=BaseSrcPanoImage::FULL_FRAME_FISHEYE;
00419 #if LF_VERSION>=MIN_LF_VERSION
00420 lfLensCalibCrop cropMode;
00421 if (lens->InterpolateCrop(lens->MinFocal,cropMode))
00422 {
00423 if(cropMode.CropMode==LF_CROP_CIRCLE)
00424 {
00425 projection=BaseSrcPanoImage::CIRCULAR_FISHEYE;
00426 return true;
00427 }
00428 };
00429 #endif
00430 return true;
00431 break;
00432 case LF_PANORAMIC:
00433 projection=BaseSrcPanoImage::PANORAMIC;
00434 return true;
00435 break;
00436 case LF_EQUIRECTANGULAR:
00437 projection=BaseSrcPanoImage::EQUIRECTANGULAR;
00438 return true;
00439 break;
00440 #if LF_VERSION>=MIN_LF_VERSION
00441
00442 case LF_FISHEYE_ORTHOGRAPHIC:
00443 projection=BaseSrcPanoImage::FISHEYE_ORTHOGRAPHIC;
00444 return true;
00445 break;
00446 case LF_FISHEYE_STEREOGRAPHIC:
00447 projection=BaseSrcPanoImage::FISHEYE_STEREOGRAPHIC;
00448 return true;
00449 break;
00450 case LF_FISHEYE_EQUISOLID:
00451 projection=BaseSrcPanoImage::FISHEYE_EQUISOLID;
00452 return true;
00453 break;
00454 case LF_FISHEYE_THOBY:
00455 projection=BaseSrcPanoImage::FISHEYE_THOBY;
00456 return true;
00457 break;
00458 #endif
00459 case LF_UNKNOWN:
00460 default:
00461 return false;
00462 break;
00463 };
00464 return false;
00465 };
00466
00469 bool TranslateProjectionHugin2LF(BaseSrcPanoImage::Projection projection, lfLens* lens)
00470 {
00471 switch(projection)
00472 {
00473 case BaseSrcPanoImage::RECTILINEAR:
00474 lens->Type=LF_RECTILINEAR;
00475 return true;
00476 break;
00477 case BaseSrcPanoImage::CIRCULAR_FISHEYE:
00478 lens->Type=LF_FISHEYE;
00479 #if LF_VERSION>=MIN_LF_VERSION
00480 lfLensCalibCrop crop;
00481 if(lens->InterpolateCrop(lens->MinFocal,crop))
00482 {
00483 if(crop.CropMode!=LF_CROP_CIRCLE)
00484 {
00485 return false;
00486 }
00487 }
00488 else
00489 {
00490 crop.Crop[0]=0;
00491 crop.Crop[1]=1;
00492 crop.Crop[2]=0;
00493 crop.Crop[3]=1;
00494 crop.CropMode=LF_CROP_CIRCLE;
00495 crop.Focal=lens->MinFocal;
00496 lens->AddCalibCrop(&crop);
00497 };
00498 #endif
00499 return true;
00500 break;
00501 case BaseSrcPanoImage::FULL_FRAME_FISHEYE:
00502 lens->Type=LF_FISHEYE;
00503 return true;
00504 break;
00505 case BaseSrcPanoImage::PANORAMIC:
00506 lens->Type=LF_PANORAMIC;
00507 return true;
00508 break;
00509 case BaseSrcPanoImage::EQUIRECTANGULAR:
00510 lens->Type=LF_EQUIRECTANGULAR;
00511 return true;
00512 break;
00513 #if LF_VERSION>=MIN_LF_VERSION
00514
00515 case BaseSrcPanoImage::FISHEYE_ORTHOGRAPHIC:
00516 lens->Type=LF_FISHEYE_ORTHOGRAPHIC;
00517 return true;
00518 break;
00519 case BaseSrcPanoImage::FISHEYE_STEREOGRAPHIC:
00520 lens->Type=LF_FISHEYE_STEREOGRAPHIC;
00521 return true;
00522 break;
00523 case BaseSrcPanoImage::FISHEYE_EQUISOLID:
00524 lens->Type=LF_FISHEYE_EQUISOLID;
00525 return true;
00526 break;
00527 case BaseSrcPanoImage::FISHEYE_THOBY:
00528 lens->Type=LF_FISHEYE_THOBY;
00529 return true;
00530 break;
00531 #endif
00532 };
00533 return false;
00534 };
00535
00536 bool LensDB::GetProjection(BaseSrcPanoImage::Projection & projection)
00537 {
00538 if(m_lenses==NULL)
00539 {
00540 return false;
00541 };
00542 return TranslateProjectionLF2Hugin(m_lenses[0],projection);
00543 };
00544
00545 bool LensDB::GetCrop(double focal,BaseSrcPanoImage::CropMode &cropMode,hugin_utils::FDiff2D &cropLeftTop,hugin_utils::FDiff2D &cropRightBottom)
00546 {
00547 if(m_lenses==NULL)
00548 {
00549 return false;
00550 };
00551 #if LF_VERSION>=MIN_LF_VERSION
00552 struct lfLensCalibCrop crop;
00553 if(m_lenses[0]->InterpolateCrop(focal,crop))
00554 {
00555 switch (crop.CropMode)
00556 {
00557 case LF_CROP_RECTANGLE:
00558 cropMode=BaseSrcPanoImage::CROP_RECTANGLE;
00559 break;
00560 case LF_CROP_CIRCLE:
00561 cropMode=BaseSrcPanoImage::CROP_CIRCLE;
00562 break;
00563 default:
00564 cropMode=BaseSrcPanoImage::NO_CROP;
00565 break;
00566 };
00567 if(cropMode!=BaseSrcPanoImage::NO_CROP)
00568 {
00569 cropLeftTop.x=crop.Crop[0];
00570 cropLeftTop.y=crop.Crop[2];
00571 cropRightBottom.x=crop.Crop[1];
00572 cropRightBottom.y=crop.Crop[3];
00573 };
00574 return true;
00575 }
00576 else
00577 {
00578 return false;
00579 };
00580 #else
00581 return false;
00582 #endif
00583 };
00584
00585 bool LensDB::GetFov(double focal,double &fov)
00586 {
00587 if(m_lenses==NULL)
00588 {
00589 return false;
00590 };
00591 #if LF_VERSION>=MIN_LF_VERSION
00592 lfLensCalibFov calibFov;
00593 if(m_lenses[0]->InterpolateFov(focal,calibFov))
00594 {
00595 fov=calibFov.FieldOfView;
00596 return true;
00597 }
00598 #endif
00599 return false;
00600 };
00601
00602 bool LensDB::GetDistortion(double focal, std::vector<double> &distortion)
00603 {
00604 distortion.clear();
00605 if(m_lenses==NULL)
00606 {
00607 return false;
00608 };
00609 lfLensCalibDistortion calibDist;
00610 if(m_lenses[0]->InterpolateDistortion(focal,calibDist))
00611 {
00612 switch(calibDist.Model)
00613 {
00614
00615
00616 case LF_DIST_MODEL_POLY3:
00617 distortion.push_back(0);
00618 distortion.push_back(calibDist.Terms[0]);
00619 distortion.push_back(0);
00620 return true;
00621 break;
00622 case LF_DIST_MODEL_PTLENS:
00623 distortion.push_back(calibDist.Terms[0]);
00624 distortion.push_back(calibDist.Terms[1]);
00625 distortion.push_back(calibDist.Terms[2]);
00626 return true;
00627 break;
00628 case LF_DIST_MODEL_NONE:
00629 case LF_DIST_MODEL_POLY5:
00630 case LF_DIST_MODEL_FOV1:
00631 default:
00632 return false;
00633 break;
00634 };
00635 }
00636 else
00637 {
00638 return false;
00639 };
00640 };
00641
00642 bool LensDB::GetVignetting(double focal, double aperture, double distance, std::vector<double> &vignetting)
00643 {
00644 vignetting.clear();
00645 if(m_lenses==NULL)
00646 {
00647 return false;
00648 };
00649 double checkedAperture=0;
00650 if(m_lenses[0]->MinAperture>0)
00651 {
00652 checkedAperture=aperture;
00653 };
00654 lfLensCalibVignetting calibVig;
00655 if(m_lenses[0]->InterpolateVignetting(focal,checkedAperture,distance,calibVig))
00656 {
00657 switch(calibVig.Model)
00658 {
00659 case LF_VIGNETTING_MODEL_PA:
00660 vignetting.push_back(1.0);
00661 vignetting.push_back(calibVig.Terms[0]);
00662 vignetting.push_back(calibVig.Terms[1]);
00663 vignetting.push_back(calibVig.Terms[2]);
00664 return true;
00665 break;
00666 case LF_VIGNETTING_MODEL_NONE:
00667 default:
00668 return false;
00669 break;
00670 };
00671 }
00672 else
00673 {
00674 return false;
00675 };
00676 };
00677
00678 bool LensDB::SaveCameraCrop(std::string filename, std::string maker, std::string model, std::string mount, double cropfactor)
00679 {
00680 #if LF_VERSION < MIN_LF_VERSION
00681
00682 char * old_locale = setlocale(LC_NUMERIC,NULL);
00683 old_locale = strdup(old_locale);
00684 setlocale(LC_NUMERIC,"C");
00685 #endif
00686
00687 if(m_newDB!=NULL)
00688 {
00689 CleanSaveInformation();
00690 };
00691 m_newDB=lf_db_new();
00692 if(!m_newDB)
00693 {
00694 m_newDB=NULL;
00695 return false;
00696 };
00697
00698 basic_path p(filename);
00699 if(boost::filesystem::exists(p))
00700 {
00701 if(boost::filesystem::is_regular_file(p))
00702 {
00703 m_newDB->Load(filename.c_str());
00704
00705 };
00706 };
00707
00708 const lfCamera **oldCameras=m_newDB->FindCameras(maker.c_str(),model.c_str());
00709 bool updateCam=false;
00710 if(oldCameras)
00711 {
00712 for(size_t i=0;oldCameras[i];i++)
00713 {
00714 updateCam=true;
00715 };
00716 };
00717
00718
00719 bool newMount=false;
00720 if(!updateCam)
00721 {
00722 newMount=IsNewMount(mount);
00723 };
00724
00725
00726 const lfCamera *const* allCameras=m_newDB->GetCameras();
00727 size_t nrCam=0;
00728 if(allCameras)
00729 {
00730 for(size_t i=0;allCameras[i];i++)
00731 {
00732 nrCam++;
00733 };
00734 };
00735
00736 if(!updateCam)
00737 {
00738 nrCam++;
00739 };
00740
00741
00742
00743 lfCamera** updatedCams=new lfCamera*[nrCam+1];
00744 for(size_t i=0;i<nrCam;i++)
00745 {
00746 updatedCams[i]=new lfCamera();
00747 };
00748 updatedCams[nrCam]=NULL;
00749
00750 for(size_t i=0;allCameras[i];i++)
00751 {
00752 lf_camera_copy(updatedCams[i],allCameras[i]);
00753 if(updateCam)
00754 {
00755 if(strcmp(allCameras[i]->Maker,oldCameras[0]->Maker)==0 &&
00756 strcmp(allCameras[i]->Model,oldCameras[0]->Model)==0)
00757 {
00758 updatedCams[i]->CropFactor=cropfactor;
00759 };
00760 };
00761 };
00762 lf_free(oldCameras);
00763 if(!updateCam)
00764 {
00765 updatedCams[nrCam-1]->SetMaker(maker.c_str());
00766 updatedCams[nrCam-1]->SetModel(model.c_str());
00767 if(mount.empty())
00768 {
00769 updatedCams[nrCam-1]->SetMount("Generic");
00770 }
00771 else
00772 {
00773 updatedCams[nrCam-1]->SetMount(mount.c_str());
00774 };
00775 updatedCams[nrCam-1]->CropFactor=cropfactor;
00776 };
00777
00778
00779 lfError e;
00780 if(newMount)
00781 {
00782 e=m_newDB->Save(filename.c_str(), m_updatedMounts, updatedCams, m_newDB->GetLenses());
00783 }
00784 else
00785 {
00786 e=m_newDB->Save(filename.c_str(),m_newDB->GetMounts(),updatedCams,m_newDB->GetLenses());
00787 };
00788
00789 if (updatedCams)
00790 {
00791 for (int i = 0; updatedCams[i]; i++)
00792 {
00793 delete updatedCams[i];
00794 };
00795 };
00796 delete []updatedCams;
00797 #if LF_VERSION < MIN_LF_VERSION
00798 setlocale(LC_NUMERIC, old_locale);
00799 free(old_locale);
00800 #endif
00801 m_newDB->Destroy();
00802 m_newDB=NULL;
00803 return e==LF_NO_ERROR;
00804 };
00805
00806 int LensDB::BeginSaveLens(std::string filename, std::string maker, std::string lensname, std::string mount, BaseSrcPanoImage::Projection projection, double cropfactor)
00807 {
00808 if(m_newDB!=NULL)
00809 {
00810 CleanSaveInformation();
00811 };
00812 m_newDB=lf_db_new();
00813 if(!m_newDB)
00814 {
00815 m_newDB=NULL;
00816 return 1;
00817 };
00818
00819 basic_path p(filename);
00820 m_lensFilename=p.string();
00821 if(boost::filesystem::exists(p))
00822 {
00823 if(boost::filesystem::is_regular_file(p))
00824 {
00825 #if LF_VERSION < MIN_LF_VERSION
00826 char * old_locale = setlocale(LC_NUMERIC,NULL);
00827 old_locale = strdup(old_locale);
00828 setlocale(LC_NUMERIC,"C");
00829 #endif
00830 m_newDB->Load(m_lensFilename.c_str());
00831
00832 #if LF_VERSION < MIN_LF_VERSION
00833 setlocale(LC_NUMERIC, old_locale);
00834 free(old_locale);
00835 #endif
00836 };
00837 };
00838
00839
00840 lfCamera* cam=NULL;
00841 if(!mount.empty())
00842 {
00843 cam=new lfCamera();
00844 cam->SetMount(mount.c_str());
00845 cam->CropFactor=cropfactor;
00846 };
00847 const lfLens **oldLenses=m_newDB->FindLenses(cam,NULL,lensname.c_str());
00848 if(cam!=NULL)
00849 {
00850 delete cam;
00851 };
00852 bool updateLens=false;
00853 if(oldLenses)
00854 {
00855 for(size_t i=0;oldLenses[i];i++)
00856 {
00857 updateLens=true;
00858 };
00859 };
00860
00861 if(updateLens)
00862 {
00863 BaseSrcPanoImage::Projection oldProjection;
00864 if(TranslateProjectionLF2Hugin(oldLenses[0],oldProjection))
00865 {
00866 if(oldProjection!=projection)
00867 {
00868
00869 lf_free(oldLenses);
00870 m_newDB->Destroy();
00871 return 2;
00872 };
00873 };
00874 if(abs(oldLenses[0]->CropFactor-cropfactor)>0.05)
00875 {
00876
00877 lf_free(oldLenses);
00878 m_newDB->Destroy();
00879 return 3;
00880 };
00881 }
00882 else
00883 {
00884 IsNewMount(mount);
00885 };
00886
00887
00888 const lfLens *const* allLenses=m_newDB->GetLenses();
00889 size_t nrLens=0;
00890 if(allLenses)
00891 {
00892 for(size_t i=0;allLenses[i];i++)
00893 {
00894 nrLens++;
00895 };
00896 };
00897
00898 if(!updateLens)
00899 {
00900 nrLens++;
00901 };
00902
00903
00904
00905 m_updatedLenses=new lfLens*[nrLens+1];
00906 for(size_t i=0;i<nrLens;i++)
00907 {
00908 m_updatedLenses[i]=new lfLens();
00909 };
00910 m_updatedLenses[nrLens]=NULL;
00911
00912 for(size_t i=0;allLenses[i];i++)
00913 {
00914 lf_lens_copy(m_updatedLenses[i],allLenses[i]);
00915 if(updateLens)
00916 {
00917 if(strcmp(m_updatedLenses[i]->Model,oldLenses[0]->Model)==0 &&
00918 strcmp(m_updatedLenses[i]->Maker,oldLenses[0]->Maker)==0)
00919 {
00920 bool compareMounts=false;
00921 if(oldLenses[0]->Mounts)
00922 {
00923 for(int j=0; oldLenses[0]->Mounts[j] && !compareMounts; j++)
00924 {
00925 for(int k=0; m_updatedLenses[i]->Mounts[k] && !compareMounts; k++)
00926 {
00927 if(strcmp(m_updatedLenses[i]->Mounts[k], oldLenses[0]->Mounts[j])==0)
00928 {
00929 compareMounts=true;
00930 };
00931 };
00932 };
00933 };
00934 if(compareMounts)
00935 {
00936 m_currentLens=m_updatedLenses[i];
00937 };
00938 };
00939 };
00940 };
00941 lf_free(oldLenses);
00942 if(!updateLens)
00943 {
00944 m_currentLens=m_updatedLenses[nrLens-1];
00945 m_currentLens->SetModel(lensname.c_str());
00946 m_currentLens->SetMaker(maker.c_str());
00947 if(mount.empty())
00948 {
00949 m_currentLens->AddMount("Generic");
00950 }
00951 else
00952 {
00953 m_currentLens->AddMount(mount.c_str());
00954 };
00955 TranslateProjectionHugin2LF(projection,m_currentLens);
00956 m_currentLens->CropFactor=cropfactor;
00957 m_currentLens->GuessParameters();
00958 };
00959 m_currentLens->Check();
00960 return 0;
00961 };
00962
00963 void LensDB::SaveHFOV(double focal, double hfov)
00964 {
00965 #if LF_VERSION>=MIN_LF_VERSION
00966 if(m_currentLens)
00967 {
00968 int index=-1;
00969 if(m_currentLens->CalibFov)
00970 {
00971 for(int i=0;m_currentLens->CalibFov[i];i++)
00972 {
00973 if(abs(m_currentLens->CalibFov[i]->Focal-focal)<0.05)
00974 {
00975 index=i;
00976 break;
00977 };
00978 };
00979 };
00980 if(index>-1)
00981 {
00982 m_currentLens->RemoveCalibFov(index);
00983 };
00984 lfLensCalibFov lcf;
00985 lcf.Focal=focal;
00986 lcf.FieldOfView=hfov;
00987 m_currentLens->AddCalibFov(&lcf);
00988 };
00989 #endif
00990 };
00991
00992 void LensDB::SaveCrop(double focal, BaseSrcPanoImage::CropMode cropMode, hugin_utils::FDiff2D cropLeftTop, hugin_utils::FDiff2D cropRightBottom)
00993 {
00994 #if LF_VERSION>=MIN_LF_VERSION
00995 if(m_currentLens)
00996 {
00997
00998
00999 int index=-1;
01000 if(m_currentLens->CalibCrop)
01001 {
01002 for(int i=0;m_currentLens->CalibCrop[i];i++)
01003 {
01004 if(m_currentLens->CalibCrop[i]->Focal==0)
01005 {
01006 index=i;
01007 break;
01008 };
01009 };
01010 };
01011 if(index>-1)
01012 {
01013 m_currentLens->RemoveCalibCrop(index);
01014 };
01015
01016 index=-1;
01017 if(m_currentLens->CalibCrop)
01018 {
01019 for(int i=0;m_currentLens->CalibCrop[i];i++)
01020 {
01021 if(abs(m_currentLens->CalibCrop[i]->Focal-focal)<0.05)
01022 {
01023 index=i;
01024 break;
01025 };
01026 };
01027 };
01028 if(index>-1)
01029 {
01030 m_currentLens->RemoveCalibCrop(index);
01031 };
01032 lfLensCalibCrop lcc;
01033 lcc.Focal=focal;
01034 switch(cropMode)
01035 {
01036 case BaseSrcPanoImage::CROP_CIRCLE:
01037 lcc.CropMode=LF_CROP_CIRCLE;
01038 break;
01039 case BaseSrcPanoImage::CROP_RECTANGLE:
01040 lcc.CropMode=LF_CROP_RECTANGLE;
01041 break;
01042 case BaseSrcPanoImage::NO_CROP:
01043 return;
01044 };
01045 lcc.Crop[0]=cropLeftTop.x;
01046 lcc.Crop[1]=cropRightBottom.x;
01047 lcc.Crop[2]=cropLeftTop.y;
01048 lcc.Crop[3]=cropRightBottom.y;
01049 m_currentLens->AddCalibCrop(&lcc);
01050 };
01051 #endif
01052 };
01053
01054 void LensDB::SaveDistortion(double focal, std::vector<double> distortion)
01055 {
01056 if(m_currentLens)
01057 {
01058 if(distortion.size()!=4)
01059 {
01060
01061 return;
01062 };
01063 int index=-1;
01064 if(m_currentLens->CalibDistortion)
01065 {
01066 for(int i=0;m_currentLens->CalibDistortion[i];i++)
01067 {
01068 if(abs(m_currentLens->CalibDistortion[i]->Focal-focal)<0.05)
01069 {
01070 index=i;
01071 break;
01072 };
01073 };
01074 };
01075 if(index>-1)
01076 {
01077 m_currentLens->RemoveCalibDistortion(index);
01078 };
01079 lfLensCalibDistortion lcd;
01080 lcd.Focal=focal;
01081 lcd.Model=LF_DIST_MODEL_PTLENS;
01082 lcd.Terms[0]=distortion[0];
01083 lcd.Terms[1]=distortion[1];
01084 lcd.Terms[2]=distortion[2];
01085 m_currentLens->AddCalibDistortion(&lcd);
01086 };
01087 };
01088
01089 void LensDB::SaveVignetting(double focal, double aperture, double distance, std::vector<double> vignetting)
01090 {
01091 if(m_currentLens)
01092 {
01093 if(vignetting.size()!=4)
01094 {
01095
01096 return;
01097 };
01098 int index=-1;
01099 if(m_currentLens->CalibVignetting)
01100 {
01101 for(int i=0;m_currentLens->CalibVignetting[i];i++)
01102 {
01103 if(abs(m_currentLens->CalibVignetting[i]->Focal-focal)<0.05 &&
01104 abs(m_currentLens->CalibVignetting[i]->Aperture-aperture)<0.05 &&
01105 abs(m_currentLens->CalibVignetting[i]->Distance-distance)<0.05)
01106 {
01107 index=i;
01108 break;
01109 };
01110 };
01111 };
01112 if(index>-1)
01113 {
01114 m_currentLens->RemoveCalibVignetting(index);
01115 };
01116 lfLensCalibVignetting lcv;
01117 lcv.Focal=focal;
01118 lcv.Aperture=aperture;
01119 lcv.Distance=distance;
01120 lcv.Model=LF_VIGNETTING_MODEL_PA;
01121 lcv.Terms[0]=vignetting[1];
01122 lcv.Terms[1]=vignetting[2];
01123 lcv.Terms[2]=vignetting[3];
01124 m_currentLens->AddCalibVignetting(&lcv);
01125 };
01126 };
01127
01128 bool LensDB::EndSaveLens()
01129 {
01130 lfError e=LF_WRONG_FORMAT;
01131 if(m_newDB!=NULL)
01132 {
01133 #if LF_VERSION < MIN_LF_VERSION
01134
01135 char * old_locale = setlocale(LC_NUMERIC,NULL);
01136 old_locale = strdup(old_locale);
01137 setlocale(LC_NUMERIC,"C");
01138 #endif
01139 m_currentLens->Check();
01140 if(m_updatedMounts!=NULL)
01141 {
01142 e=m_newDB->Save(m_lensFilename.c_str(),m_updatedMounts,m_newDB->GetCameras(),m_updatedLenses);
01143 }
01144 else
01145 {
01146 e=m_newDB->Save(m_lensFilename.c_str(),m_newDB->GetMounts(),m_newDB->GetCameras(),m_updatedLenses);
01147 };
01148 m_lensFilename.clear();
01149 #if LF_VERSION < MIN_LF_VERSION
01150 setlocale(LC_NUMERIC,old_locale);
01151 free(old_locale);
01152 #endif
01153 CleanSaveInformation();
01154 };
01155 return e==LF_NO_ERROR;
01156 };
01157
01158 void LensDB::CleanSaveInformation()
01159 {
01160 CleanUpdatedMounts();
01161 if (m_updatedLenses!=NULL)
01162 {
01163 for (int i = 0; m_updatedLenses[i]; i++)
01164 {
01165 delete m_updatedLenses[i];
01166 };
01167 delete []m_updatedLenses;
01168 m_updatedLenses=NULL;
01169 };
01170 if(m_newDB!=NULL)
01171 {
01172 m_newDB->Destroy();
01173 m_newDB=NULL;
01174 };
01175 };
01176
01177 bool LensDB::IsNewMount(std::string newMount)
01178 {
01179 CleanUpdatedMounts();
01180
01181 const lfMount* mount=m_db->FindMount(newMount.c_str());
01182 if(mount)
01183 {
01184 return false;
01185 };
01186
01187 mount=NULL;
01188 mount=m_newDB->FindMount(newMount.c_str());
01189 if(mount)
01190 {
01191 return false;
01192 };
01193
01194 const lfMount *const* allMounts=m_newDB->GetMounts();
01195 size_t nrMounts=0;
01196 if(allMounts)
01197 {
01198 for(size_t i=0;allMounts[i];i++)
01199 {
01200 nrMounts++;
01201 };
01202 };
01203 nrMounts++;
01204
01205
01206
01207 m_updatedMounts=new lfMount*[nrMounts+1];
01208 m_updatedMounts[nrMounts]=NULL;
01209
01210 for(size_t i=0;allMounts[i];i++)
01211 {
01212
01213 m_updatedMounts[i]=new lfMount(*allMounts[i]);
01214 };
01215
01216 m_updatedMounts[nrMounts-1]=new lfMount();
01217 m_updatedMounts[nrMounts-1]->SetName(newMount.c_str());
01218 m_updatedMounts[nrMounts-1]->AddCompat("Generic");
01219 return true;
01220 };
01221
01222 void LensDB::CleanUpdatedMounts()
01223 {
01224 if (m_updatedMounts!=NULL)
01225 {
01226 for (int i = 0; m_updatedMounts[i]; i++)
01227 {
01228 delete m_updatedMounts[i];
01229 };
01230 delete []m_updatedMounts;
01231 m_updatedMounts=NULL;
01232 };
01233 };
01234
01235 LensDBList::LensDBList()
01236 {
01237 m_lenses=NULL;
01238 };
01239
01240 LensDBList::~LensDBList()
01241 {
01242 if(m_lenses)
01243 {
01244 lf_free(m_lenses);
01245 };
01246 };
01247
01248 const size_t LensDBList::GetLensCount() const
01249 {
01250 return m_lensCount;
01251 };
01252
01253 const lfLens* LensDBList::GetLens(size_t index) const
01254 {
01255 if(index<m_lensCount)
01256 {
01257 return m_lenses[index];
01258 }
01259 else
01260 {
01261 return NULL;
01262 };
01263 };
01264
01265 void LensDBList::SetLenses(const lfLens** lenses)
01266 {
01267 if(m_lenses)
01268 {
01269 lf_free(m_lenses);
01270 };
01271 m_lenses=lenses;
01272 m_lensCount=0;
01273 if(m_lenses)
01274 {
01275 for(size_t i=0;m_lenses[i];i++)
01276 {
01277 m_lensCount++;
01278 };
01279 };
01280 };
01281
01282 std::string LensDBList::GetLensName(size_t index) const
01283 {
01284 if(index>=m_lensCount)
01285 {
01286 return "";
01287 };
01288 std::string lensname=m_lenses[index]->Model;
01289 if(lensname=="Standard")
01290 {
01291 return m_camModel + " (" + m_camMaker + ")";
01292 }
01293 else
01294 {
01295 return lensname + " (Focal length multiplier: " + hugin_utils::doubleToString(m_lenses[index]->CropFactor,1) +")";
01296 };
01297 };
01298
01299 void LensDBList::SetCameraModelMaker(const std::string camMaker, const std::string camModel)
01300 {
01301 m_camMaker=camMaker;
01302 m_camModel=camModel;
01303 };
01304
01305 }
01306 }