LensDB.cpp

Go to the documentation of this file.
00001 
00008 /*  This program is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This software is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public
00019  *  License along with this software. If not, see
00020  *  <http://www.gnu.org/licenses/>.
00021  *
00022  */
00023 
00024 #include "LensDB.h"
00025 #include <iostream>
00026 #include <sstream>
00027 #include <fstream>
00028 #include <hugin_utils/stl_utils.h>
00029 #include <hugin_utils/utils.h>
00030 #include <sqlite3.h>
00031 #include <panodata/StandardImageVariableGroups.h>
00032 #include <algorithms/basic/CalculateCPStatistics.h>
00033 
00034 namespace HuginBase
00035 {
00036 
00037 namespace LensDB
00038 {
00039 
00040 LensDB* LensDB::m_instance=NULL;
00041 
00042 // internal class to handle all transfer from/to database
00043 // to prevent including of sqlite3.h into hugin_base header
00044 class LensDB::Database
00045 {
00046 public:
00047     //struct for retrieving lens data
00048     struct HFOVData
00049     {
00050         double focallength;
00051         double HFOV;
00052     };
00053     struct CropData
00054     {
00055         double focallength;
00056         int left, right, top, bottom;
00057     };
00058     struct Distortiondata
00059     {
00060         double focallength;
00061         double a, b, c;
00062     };
00063     struct Vignettingdata
00064     {
00065         double focallength;
00066         double aperture;
00067         double distance;
00068         double Vb, Vc, Vd;
00069     };
00070     struct TCAdata
00071     {
00072         double focallength;
00073         double ra, rb, rc, rd;
00074         double ba, bb, bc, bd;
00075     };
00076     //constructor, open database
00077     explicit Database(const std::string& filename) : m_filename(filename), m_runningTransaction(false)
00078     {
00079         bool newDB = (!hugin_utils::FileExists(m_filename));
00080         int error = sqlite3_open(m_filename.c_str(), &m_db);
00081         if (error)
00082         {
00083             std::cerr << "Can't open database: " << sqlite3_errmsg(m_db) << std::endl;
00084             m_db = NULL;
00085             m_filename = std::string();
00086         };
00087         if (newDB)
00088         {
00089             if (!CreateTables())
00090             {
00091                 //something went wrong with the generation of the database structure
00092                 sqlite3_close(m_db);
00093                 m_db = NULL;
00094                 m_filename = std::string();
00095             };
00096         }
00097         else
00098         {
00099             // check version and update database when necessary
00100             // not yet implemented
00101             // if (GetDBVersion() < 2) UpdateDatabase();
00102         };
00103     };
00104     // destructor, destroy database
00105     ~Database()
00106     {
00107         if (m_db)
00108         {
00109             if (m_runningTransaction)
00110             {
00111                 EndTransaction();
00112             };
00113             sqlite3_close(m_db);
00114         };
00115     };
00116     // create the tables for the database
00117     bool CreateTables()
00118     {
00119         const char* createDB = "PRAGMA user_version=1;"
00120             "CREATE TABLE CameraCropTable (Maker TEXT, Model TEXT, Cropfactor REAL, PRIMARY KEY (Maker, Model));"
00121             "CREATE TABLE LensProjectionTable (Lens TEXT PRIMARY KEY, Projection INTEGER);"
00122             "CREATE TABLE LensHFOVTable (Lens TEXT, Focallength REAL, HFOV REAL, Weight INTEGER);"
00123             "CREATE INDEX HFOV_IndexLens ON LensHFOVTable (Lens);"
00124             "CREATE INDEX HFOV_IndexLens2 ON LensHFOVTable (Lens, Focallength);"
00125             "CREATE TABLE LensCropTable (Lens TEXT, Focallength REAL, Width INTEGER, Height INTEGER, CropLeft INTEGER, CropRight INTEGER, CropTop INTEGER, CropBottom INTEGER, PRIMARY KEY (Lens, Focallength, Width, Height));"
00126             "CREATE TABLE DistortionTable(Lens TEXT, Focallength REAL, a REAL, b REAL, c REAL, Weight INTEGER);"
00127             "CREATE INDEX Dist_IndexLens ON DistortionTable (Lens);"
00128             "CREATE INDEX Dist_IndexLensFocal ON DistortionTable (Lens, Focallength);"
00129             "CREATE TABLE VignettingTable (Lens TEXT, Focallength REAL, Aperture REAL, Distance REAL, Vb REAL, Vc REAL, Vd REAL, Weight INTEGER);"
00130             "CREATE INDEX Vig_IndexLens ON VignettingTable (Lens);"
00131             "CREATE INDEX Vig_IndexLensFocal ON VignettingTable (Lens, Focallength);"
00132             "CREATE INDEX Vig_IndexLensFocalApertureDistance ON VignettingTable (Lens, Focallength, Aperture, Distance);"
00133             "CREATE TABLE TCATable (Lens TEXT, Focallength REAL, ra REAL, rb REAL, rc REAL, rd REAL, ba REAL, bb REAL, bc REAL, bd REAL, Weight INTEGER);"
00134             "CREATE INDEX TCA_IndexLens ON TCATable (Lens);"
00135             "CREATE INDEX TCA_IndexLensFocal ON TCATable (Lens, Focallength);"
00136             "CREATE TABLE EMORTable (Maker TEXT, Model TEXT, ISO INTEGER, Ra REAL, Rb REAL, Rc REAL, Rd REAL, Re REAL, Weight INTEGER);"
00137             "CREATE INDEX EMOR_Index_Cam ON EMORTable (Maker, Model);"
00138             "CREATE INDEX EMOR_Index_CamISO ON EMORTable (Maker, Model, ISO);";
00139         if (m_db == NULL)
00140         {
00141             return false;
00142         };
00143         if (sqlite3_exec(m_db, createDB, NULL, NULL, NULL) == SQLITE_OK)
00144         {
00145             return true;
00146         }
00147         else
00148         {
00149             std::cerr << "Could not create database structure." << std::endl;
00150             return false;
00151         };
00152     };
00153     // report the database version, implemented by PRAGMA user_version
00154     // currently not used, for further extensions of the database structure
00155     // @return db version, or -1 if db could not opened/initialized
00156     int GetDBVersion() const
00157     {
00158         if (m_db == NULL)
00159         {
00160             return -1;
00161         };
00162         sqlite3_stmt *statement;
00163         const char *tail;
00164         int version = 0;
00165         if (sqlite3_prepare_v2(m_db, "PRAGMA user_version;", -1, &statement, &tail) == SQLITE_OK)
00166         {
00167             if (sqlite3_step(statement) == SQLITE_ROW)
00168             {
00169                 version = sqlite3_column_int(statement, 0);
00170             };
00171         };
00172         sqlite3_finalize(statement);
00173         return version;
00174     };
00175     // returns the filename of the database
00176     std::string GetDBFilename() const
00177     {
00178         return m_filename;
00179     };
00180     // search for the crop factor of the given camera in the database
00181     // returns true of camera was found, otherwise false
00182     bool GetCropFactor(const std::string& maker, const std::string& model, double &cropFactor) const
00183     {
00184         cropFactor = 0;
00185         if (m_db == NULL)
00186         {
00187             return false;
00188         };
00189         sqlite3_stmt *statement;
00190         const char *tail;
00191         if (sqlite3_prepare_v2(m_db, "SELECT Cropfactor FROM CameraCropTable WHERE Maker=?1 AND Model=?2;", -1, &statement, &tail) == SQLITE_OK)
00192         {
00193             sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
00194             sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
00195             if (sqlite3_step(statement) == SQLITE_ROW)
00196             {
00197                 cropFactor = sqlite3_column_double(statement, 0);
00198             };
00199         };
00200         sqlite3_finalize(statement);
00201         if (cropFactor < 0.1 || cropFactor>100)
00202         {
00203             cropFactor = 0;
00204         };
00205         return cropFactor > 0.1;
00206     };
00207     // saves the crop factor for the given camera in the database
00208     // returns true, if data were successful saved into db, false if errors occured during saving
00209     bool SaveCropFactor(const std::string& maker, const std::string& model, const double cropFactor)
00210     {
00211         if (m_db == NULL)
00212         {
00213             return false;
00214         };
00215         // do some range checking
00216         if (cropFactor < 0.1 || cropFactor > 100)
00217         {
00218             return false;
00219         };
00220         sqlite3_stmt *statement;
00221         const char *tail;
00222         int returnValue = 0;
00223         BeginTransaction();
00224         if (sqlite3_prepare_v2(m_db, "INSERT OR FAIL INTO CameraCropTable (Maker, Model, Cropfactor) VALUES(?1,?2,?3);", -1, &statement, &tail) == SQLITE_OK)
00225         {
00226             sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
00227             sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
00228             sqlite3_bind_double(statement, 3, cropFactor);
00229             returnValue = sqlite3_step(statement);
00230             if (returnValue == SQLITE_CONSTRAINT)
00231             {
00232                 sqlite3_finalize(statement);
00233                 if (sqlite3_prepare_v2(m_db, "UPDATE CameraCropTable SET Cropfactor=?3 WHERE Maker=?1 AND Model=?2;", -1, &statement, &tail) == SQLITE_OK)
00234                 {
00235                     sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
00236                     sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
00237                     sqlite3_bind_double(statement, 3, cropFactor);
00238                     returnValue = sqlite3_step(statement);
00239                 };
00240             };
00241         };
00242         sqlite3_finalize(statement);
00243         EndTransaction();
00244         return returnValue == SQLITE_DONE;
00245     };
00246     // search for the projection of the given lens in the database
00247     // returns true if lens information were was found, otherwise false
00248     bool GetLensProjection(const std::string& lens, int &projection) const
00249     {
00250         projection = -1;
00251         if (m_db == NULL)
00252         {
00253             return false;
00254         };
00255         sqlite3_stmt *statement;
00256         const char *tail;
00257         if (sqlite3_prepare_v2(m_db, "SELECT Projection FROM LensProjectionTable WHERE Lens=?1;", -1, &statement, &tail) == SQLITE_OK)
00258         {
00259             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00260             if (sqlite3_step(statement) == SQLITE_ROW)
00261             {
00262                 projection = sqlite3_column_int(statement, 0);
00263             };
00264         };
00265         sqlite3_finalize(statement);
00266         return projection != -1;
00267     };
00268     // saves the projection for the given lens in the database
00269     // returns true, if data were successful saved into db, false if errors occured during saving
00270     bool SaveLensProjection(const std::string& lens, const int projection)
00271     {
00272         if (m_db == NULL)
00273         {
00274             return false;
00275         };
00276         sqlite3_stmt *statement;
00277         const char *tail;
00278         int returnValue = 0;
00279         BeginTransaction();
00280         if (sqlite3_prepare_v2(m_db, "INSERT OR FAIL INTO LensProjectionTable (Lens, Projection) VALUES(?1,?2);", -1, &statement, &tail) == SQLITE_OK)
00281         {
00282             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00283             sqlite3_bind_int(statement, 2, projection);
00284             returnValue = sqlite3_step(statement);
00285             if (returnValue == SQLITE_CONSTRAINT)
00286             {
00287                 sqlite3_finalize(statement);
00288                 if (sqlite3_prepare_v2(m_db, "UPDATE LensProjectionTable SET Projection=?2 WHERE Lens=?1;", -1, &statement, &tail) == SQLITE_OK)
00289                 {
00290                     sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00291                     sqlite3_bind_int(statement, 2, projection);
00292                     returnValue = sqlite3_step(statement);
00293                 };
00294             };
00295         };
00296         sqlite3_finalize(statement);
00297         EndTransaction();
00298         return returnValue == SQLITE_DONE;
00299     };
00300     // search for the HFOV for the given lens in the database
00301     // returns true of data for lens was found, otherwise false
00302     // returns 2 datasets with the values for the 2 focal lengths
00303     bool GetHFOV(const std::string& lens, const double focallength, std::vector<HFOVData>& hfovData) const
00304     {
00305         hfovData.clear();
00306         if (m_db == NULL)
00307         {
00308             return false;
00309         };
00310         sqlite3_stmt *statement;
00311         const char *tail;
00312         if (sqlite3_prepare_v2(m_db, "SELECT Focallength, SUM(HFOV*Weight)/SUM(Weight) FROM LensHFOVTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
00313         {
00314             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00315             sqlite3_bind_double(statement, 2, focallength);
00316             while (sqlite3_step(statement) == SQLITE_ROW)
00317             {
00318                 HFOVData newhfovData;
00319                 newhfovData.focallength = sqlite3_column_double(statement, 0);
00320                 newhfovData.HFOV = sqlite3_column_double(statement, 1);
00321                 hfovData.push_back(newhfovData);
00322             };
00323         };
00324         sqlite3_finalize(statement);
00325         return !hfovData.empty();
00326     };
00327     // saves the HFOV data in the database
00328     // returns true, if data were successful saved into db, false if errors occured during saving
00329     bool SaveHFOV(const std::string& lens, const double focallength, const double HFOV, const int weight = 10)
00330     {
00331         if (m_db == NULL)
00332         {
00333             return false;
00334         };
00335         // range checking
00336         if (HFOV < 0.1 || HFOV>360)
00337         {
00338             return false;
00339         };
00340         sqlite3_stmt *statement;
00341         const char *tail;
00342         int returnValue = 0;
00343         if (sqlite3_prepare_v2(m_db, "INSERT INTO LensHFOVTable(Lens, Focallength, HFOV, Weight) VALUES(?1,?2,?3,?4);", -1, &statement, &tail) == SQLITE_OK)
00344         {
00345             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00346             sqlite3_bind_double(statement, 2, focallength);
00347             sqlite3_bind_double(statement, 3, HFOV);
00348             sqlite3_bind_int(statement, 4, weight);
00349             returnValue = sqlite3_step(statement);
00350         };
00351         sqlite3_finalize(statement);
00352         return returnValue == SQLITE_DONE;
00353     };
00354     // search for the crop of the given lens in the database
00355     // returns true if lens information were was found, otherwise false
00356     bool GetLensCrop(const std::string& lens, const double focal, const int width, const int height, std::vector<CropData> &cropData) const
00357     {
00358         cropData.clear();
00359         if (m_db == NULL)
00360         {
00361             return false;
00362         };
00363         sqlite3_stmt *statement;
00364         const char *tail;
00365         if (sqlite3_prepare_v2(m_db, "SELECT Focallength, CropLeft, CropRight, CropTop, CropBottom FROM LensCropTable WHERE Lens=?1 AND Width=?2 AND Height=?3 ORDER BY ABS(Focallength-?4) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
00366         {
00367             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00368             sqlite3_bind_int(statement, 2, width);
00369             sqlite3_bind_int(statement, 3, height);
00370             sqlite3_bind_double(statement, 4, focal);
00371             while (sqlite3_step(statement) == SQLITE_ROW)
00372             {
00373                 CropData newCropData;
00374                 newCropData.focallength = sqlite3_column_double(statement, 0);
00375                 newCropData.left = sqlite3_column_int(statement, 1);
00376                 newCropData.right = sqlite3_column_int(statement, 2);
00377                 newCropData.top = sqlite3_column_int(statement, 3);
00378                 newCropData.bottom = sqlite3_column_int(statement, 4);
00379                 cropData.push_back(newCropData);
00380             };
00381         };
00382         sqlite3_finalize(statement);
00383         return !cropData.empty();
00384     };
00385     // saves the crop for the given lens in the database
00386     // returns true, if data were successful saved into db, false if errors occured during saving
00387     bool SaveLensCrop(const std::string& lens, const double focal, const int width, const int height, const int left, const int right, const int top, const int bottom)
00388     {
00389         if (m_db == NULL)
00390         {
00391             return false;
00392         };
00393         sqlite3_stmt *statement;
00394         const char *tail;
00395         int returnValue = 0;
00396         BeginTransaction();
00397         if (sqlite3_prepare_v2(m_db, "INSERT OR FAIL INTO LensCropTable (Lens, Focallength, Width, Height, CropLeft, CropRight, CropTop, CropBottom) VALUES(?1,?2,?3,?4,?5,?6,?7,?8);", -1, &statement, &tail) == SQLITE_OK)
00398         {
00399             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00400             sqlite3_bind_double(statement, 2, focal);
00401             sqlite3_bind_int(statement, 3, width);
00402             sqlite3_bind_int(statement, 4, height);
00403             sqlite3_bind_int(statement, 5, left);
00404             sqlite3_bind_int(statement, 6, right);
00405             sqlite3_bind_int(statement, 7, top);
00406             sqlite3_bind_int(statement, 8, bottom);
00407             returnValue = sqlite3_step(statement);
00408             if (returnValue == SQLITE_CONSTRAINT)
00409             {
00410                 sqlite3_finalize(statement);
00411                 if (sqlite3_prepare_v2(m_db, "UPDATE LensCropTable SET CropLeft=?5, CropRight=?6, CropTop=?7, CropBottom=?8 WHERE Lens=?1 AND Focallength=?2 AND Width=?3 AND Height=?4;", -1, &statement, &tail) == SQLITE_OK)
00412                 {
00413                     sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00414                     sqlite3_bind_double(statement, 2, focal);
00415                     sqlite3_bind_int(statement, 3, width);
00416                     sqlite3_bind_int(statement, 4, height);
00417                     sqlite3_bind_int(statement, 5, left);
00418                     sqlite3_bind_int(statement, 6, right);
00419                     sqlite3_bind_int(statement, 7, top);
00420                     sqlite3_bind_int(statement, 8, bottom);
00421                     returnValue = sqlite3_step(statement);
00422                 };
00423             };
00424         };
00425         sqlite3_finalize(statement);
00426         EndTransaction();
00427         return returnValue == SQLITE_DONE;
00428     };
00429     // removes the crop information for the given focallength and imagesize
00430     bool RemoveLensCrop(const std::string& lens, const double focal, const int width, const int height)
00431     {
00432         if (m_db == NULL)
00433         {
00434             return false;
00435         };
00436         sqlite3_stmt *statement;
00437         const char *tail;
00438         int returnValue = 0;
00439         if (sqlite3_prepare_v2(m_db, "DELETE FROM LensCropTable WHERE Lens=?1 AND Focallength=?2 AND Width=?3 AND Height=?4;", -1, &statement, &tail) == SQLITE_OK)
00440         {
00441             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00442             sqlite3_bind_double(statement, 2, focal);
00443             sqlite3_bind_int(statement, 3, width);
00444             sqlite3_bind_int(statement, 4, height);
00445             returnValue = sqlite3_step(statement);
00446         };
00447         sqlite3_finalize(statement);
00448         EndTransaction();
00449         return returnValue == SQLITE_DONE;
00450     };
00451 
00452     // search for the distortion data for the given lens in the database
00453     // returns true of data for lens was found, otherwise false
00454     // returns 2 datasets with the values for the 2 nearest focal lengths
00455     bool GetDistortionData(const std::string& lens, const double focallength, std::vector<Distortiondata>& distData) const
00456     {
00457         distData.clear();
00458         if (m_db == NULL)
00459         {
00460             return false;
00461         };
00462         sqlite3_stmt *statement;
00463         const char *tail;
00464         if (sqlite3_prepare_v2(m_db, "SELECT Focallength, SUM(a*Weight)/SUM(Weight), SUM(b*Weight)/SUM(Weight), SUM(c*Weight)/SUM(Weight) FROM DistortionTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
00465         {
00466             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00467             sqlite3_bind_double(statement, 2, focallength);
00468             while (sqlite3_step(statement) == SQLITE_ROW)
00469             {
00470                 Distortiondata newDistData;
00471                 newDistData.focallength = sqlite3_column_double(statement, 0);
00472                 newDistData.a = sqlite3_column_double(statement, 1);
00473                 newDistData.b = sqlite3_column_double(statement, 2);
00474                 newDistData.c = sqlite3_column_double(statement, 3);
00475                 distData.push_back(newDistData);
00476             };
00477         };
00478         sqlite3_finalize(statement);
00479         return !distData.empty();
00480     };
00481     // saves the distortion data in the database
00482     // returns true, if data were successful saved into db, false if errors occured during saving
00483     bool SaveDistortion(const std::string& lens, const double focallength, const double a, const double b, const double c, const int weight = 10)
00484     {
00485         if (m_db == NULL)
00486         {
00487             return false;
00488         };
00489         sqlite3_stmt *statement;
00490         const char *tail;
00491         int returnValue = 0;
00492         if (sqlite3_prepare_v2(m_db, "INSERT INTO DistortionTable(Lens, Focallength, a, b, c, Weight) VALUES(?1,?2,?3,?4,?5,?6);", -1, &statement, &tail) == SQLITE_OK)
00493         {
00494             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00495             sqlite3_bind_double(statement, 2, focallength);
00496             sqlite3_bind_double(statement, 3, a);
00497             sqlite3_bind_double(statement, 4, b);
00498             sqlite3_bind_double(statement, 5, c);
00499             sqlite3_bind_int(statement, 6, weight);
00500             returnValue = sqlite3_step(statement);
00501         };
00502         sqlite3_finalize(statement);
00503         return returnValue == SQLITE_DONE;
00504     };
00505     // search for the vignetting data for the given lens in the database
00506     // returns true of data for lens was found, otherwise false
00507     // returns maximal 4 datasets: datasets of the 2 nearest focallengths and for each focallength the 2 nearest apertures
00508     bool GetVignettingData(const std::string& lens, const double focallength, const double aperture, std::vector<Vignettingdata>& vigData) const
00509     {
00510         vigData.clear();
00511         if (m_db == NULL)
00512         {
00513             return false;
00514         };
00515         sqlite3_stmt *statement;
00516         const char *tail;
00517         if (sqlite3_prepare_v2(m_db,
00518             "SELECT Focallength, Aperture, SUM(Vb*Weight)/SUM(Weight), SUM(Vc*Weight)/SUM(Weight), SUM(Vd*Weight)/SUM(Weight) FROM VignettingTable "
00519             "WHERE Lens = ?1 AND ("
00520             "("
00521             "Focallength IN "
00522             "(SELECT Focallength FROM VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1) "
00523             "AND Aperture IN "
00524             "(SELECT Aperture FROM VignettingTable WHERE Lens=?1 AND "
00525             "Focallength IN "
00526             "(SELECT Focallength from VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1) "
00527             "GROUP BY Aperture ORDER BY ABS(Aperture-?3) LIMIT 2)"
00528             ") OR ("
00529             "Focallength IN "
00530             "(SELECT Focallength FROM VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1 OFFSET 1) "
00531             "AND Aperture IN "
00532             "(SELECT Aperture FROM VignettingTable WHERE Lens=?1 AND "
00533             "Focallength IN "
00534             "(SELECT Focallength FROM VignettingTable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) LIMIT 1 OFFSET 1) "
00535             "GROUP BY Aperture ORDER BY ABS(Aperture-?3) LIMIT 2)"
00536             ")"
00537             ")"
00538             "GROUP BY Focallength, Aperture ORDER BY Focallength, Aperture;",
00539             -1, &statement, &tail) == SQLITE_OK)
00540         {
00541             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00542             sqlite3_bind_double(statement, 2, focallength);
00543             sqlite3_bind_double(statement, 3, aperture);
00544             while (sqlite3_step(statement) == SQLITE_ROW)
00545             {
00546                 Vignettingdata newVigData;
00547                 newVigData.focallength = sqlite3_column_double(statement, 0);
00548                 newVigData.aperture = sqlite3_column_double(statement, 1);
00549                 newVigData.Vb = sqlite3_column_double(statement, 2);
00550                 newVigData.Vc = sqlite3_column_double(statement, 3);
00551                 newVigData.Vd = sqlite3_column_double(statement, 4);
00552                 vigData.push_back(newVigData);
00553             };
00554         };
00555         sqlite3_finalize(statement);
00556         return !vigData.empty();
00557     };
00558     // saves the vignetting data in the database
00559     // returns true, if data were successful saved into db, false if errors occured during saving
00560     bool SaveVignetting(const std::string& lens, const double focallength, const double aperture, const double distance, const double Vb, const double Vc, const double Vd, const int weight = 10)
00561     {
00562         if (m_db == NULL)
00563         {
00564             return false;
00565         };
00566         sqlite3_stmt *statement;
00567         const char *tail;
00568         int returnValue = 0;
00569         if (sqlite3_prepare_v2(m_db, "INSERT INTO VignettingTable(Lens, Focallength, Aperture, Distance, Vb, Vc, Vd, Weight) VALUES(?1,?2,?3,?4,?5,?6,?7,?8);", -1, &statement, &tail) == SQLITE_OK)
00570         {
00571             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00572             sqlite3_bind_double(statement, 2, focallength);
00573             sqlite3_bind_double(statement, 3, aperture);
00574             sqlite3_bind_double(statement, 4, distance);
00575             sqlite3_bind_double(statement, 5, Vb);
00576             sqlite3_bind_double(statement, 6, Vc);
00577             sqlite3_bind_double(statement, 7, Vd);
00578             sqlite3_bind_int(statement, 8, weight);
00579             returnValue = sqlite3_step(statement);
00580         };
00581         sqlite3_finalize(statement);
00582         return returnValue == SQLITE_DONE;
00583     };
00584     // search for the tca data for the given lens in the database
00585     // returns true of data for lens was found, otherwise false
00586     // returns 2 datasets with the values for the 2 nearest focal lengths
00587     bool GetTCAData(const std::string& lens, const double focallength, std::vector<TCAdata>& tcaData) const
00588     {
00589         tcaData.clear();
00590         if (m_db == NULL)
00591         {
00592             return false;
00593         };
00594         sqlite3_stmt *statement;
00595         const char *tail;
00596         if (sqlite3_prepare_v2(m_db, "SELECT Focallength, SUM(ra*Weight)/SUM(Weight), SUM(rb*Weight)/SUM(Weight), SUM(rc*Weight)/SUM(Weight), SUM(rd*Weight)/SUM(Weight), SUM(ba*Weight)/SUM(Weight), SUM(bb*Weight)/SUM(Weight), SUM(bc*Weight)/SUM(Weight), SUM(bd*Weight)/SUM(Weight) FROM TCATable WHERE Lens=?1 GROUP BY Focallength ORDER BY ABS(Focallength-?2) ASC LIMIT 2;", -1, &statement, &tail) == SQLITE_OK)
00597         {
00598             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00599             sqlite3_bind_double(statement, 2, focallength);
00600             while (sqlite3_step(statement) == SQLITE_ROW)
00601             {
00602                 TCAdata newTCAData;
00603                 newTCAData.focallength = sqlite3_column_double(statement, 0);
00604                 newTCAData.ra = sqlite3_column_double(statement, 1);
00605                 newTCAData.rb = sqlite3_column_double(statement, 2);
00606                 newTCAData.rc = sqlite3_column_double(statement, 3);
00607                 newTCAData.rd = sqlite3_column_double(statement, 4);
00608                 newTCAData.ba = sqlite3_column_double(statement, 5);
00609                 newTCAData.bb = sqlite3_column_double(statement, 6);
00610                 newTCAData.bc = sqlite3_column_double(statement, 7);
00611                 newTCAData.bd = sqlite3_column_double(statement, 8);
00612                 tcaData.push_back(newTCAData);
00613             };
00614         };
00615         sqlite3_finalize(statement);
00616         return !tcaData.empty();
00617     };
00618     // saves the tca data in the database
00619     // returns true, if data were successful saved into db, false if errors occured during saving
00620     bool SaveTCAData(const std::string& lens, const double focallength, const double ra, const double rb, const double rc, const double rd,
00621         const double ba, const double bb, const double bc, const double bd, const int weight = 10)
00622     {
00623         if (m_db == NULL)
00624         {
00625             return false;
00626         };
00627         sqlite3_stmt *statement;
00628         const char *tail;
00629         int returnValue = 0;
00630         if (sqlite3_prepare_v2(m_db, "INSERT INTO TCATable(Lens, Focallength, ra, rb, rc, rd, ba, bb, bc, bd, Weight) VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11);", -1, &statement, &tail) == SQLITE_OK)
00631         {
00632             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
00633             sqlite3_bind_double(statement, 2, focallength);
00634             sqlite3_bind_double(statement, 3, ra);
00635             sqlite3_bind_double(statement, 4, rb);
00636             sqlite3_bind_double(statement, 5, rc);
00637             sqlite3_bind_double(statement, 6, rd);
00638             sqlite3_bind_double(statement, 7, ba);
00639             sqlite3_bind_double(statement, 8, bb);
00640             sqlite3_bind_double(statement, 9, bc);
00641             sqlite3_bind_double(statement, 10, bd);
00642             sqlite3_bind_int(statement, 11, weight);
00643             returnValue = sqlite3_step(statement);
00644         };
00645         sqlite3_finalize(statement);
00646         return returnValue == SQLITE_DONE;
00647     };
00648     // saves the EMoR data in the database
00649     // returns true, if data were successful saved into db, false if errors occured during saving
00650     bool SaveEMoR(const std::string& maker, const std::string& model, const int iso, const double Ra, const double Rb, const double Rc, const double Rd, const double Re, const int weight = 10)
00651     {
00652         if (m_db == NULL)
00653         {
00654             return false;
00655         };
00656         sqlite3_stmt *statement;
00657         const char *tail;
00658         int returnValue = 0;
00659         if (sqlite3_prepare_v2(m_db, "INSERT INTO EMORTable(Maker, Model, ISO, Ra, Rb, Rc, Rd, Re, Weight) VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9);", -1, &statement, &tail) == SQLITE_OK)
00660         {
00661             sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
00662             sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
00663             sqlite3_bind_int(statement, 3, iso);
00664             sqlite3_bind_double(statement, 4, Ra);
00665             sqlite3_bind_double(statement, 5, Rb);
00666             sqlite3_bind_double(statement, 6, Rc);
00667             sqlite3_bind_double(statement, 7, Rd);
00668             sqlite3_bind_double(statement, 8, Re);
00669             sqlite3_bind_int(statement, 9, weight);
00670             returnValue = sqlite3_step(statement);
00671         };
00672         sqlite3_finalize(statement);
00673         return returnValue == SQLITE_DONE;
00674     };
00675     // return a list of lens names which has certain information
00676     bool GetLensNames(const bool distortion, const bool vignetting, const bool tca, LensList& lensList) const
00677     {
00678         lensList.clear();
00679         if (m_db == NULL)
00680         {
00681             return false;
00682         };
00683         sqlite3_stmt *statement;
00684         const std::string statement_distortion("SELECT DISTINCT Lens FROM DistortionTable");
00685         const std::string statement_vignetting("SELECT DISTINCT Lens FROM VignettingTable");
00686         const std::string statement_tca("SELECT DISTINCT Lens FROM TCATable");
00687         std::string statementString;
00688         if (distortion)
00689         {
00690             statementString = statement_distortion;
00691         };
00692         if (vignetting)
00693         {
00694             if (!statementString.empty())
00695             {
00696                 statementString.append(" UNION ");
00697             };
00698             statementString.append(statement_vignetting);
00699         };
00700         if (tca)
00701         {
00702             if (!statementString.empty())
00703             {
00704                 statementString.append(" UNION ");
00705             };
00706             statementString.append(statement_tca);
00707         };
00708         if (statementString.empty())
00709         {
00710             return false;
00711         };
00712         const char *tail;
00713         if (sqlite3_prepare_v2(m_db, statementString.c_str(), -1, &statement, &tail) == SQLITE_OK)
00714         {
00715             while (sqlite3_step(statement) == SQLITE_ROW)
00716             {
00717                 std::stringstream stream;
00718                 stream << sqlite3_column_text(statement, 0);
00719                 lensList.push_back(stream.str());
00720             };
00721         };
00722         sqlite3_finalize(statement);
00723         return !lensList.empty();
00724     };
00725     // clean up data base
00726     bool CleanUp()
00727     {
00728         if (m_db == NULL)
00729         {
00730             return false;
00731         };
00732         BeginTransaction();
00733         sqlite3_exec(m_db,
00734             "INSERT INTO DistortionTable(Lens, Focallength, a, b, c, Weight) "
00735             "SELECT Lens, Focallength, SUM(a*Weight)/SUM(Weight), SUM(b*Weight)/SUM(Weight), SUM(c*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM DistortionTable GROUP By Lens, Focallength;"
00736             "DELETE FROM DistortionTable WHERE Weight>=0;"
00737             "UPDATE DistortionTable SET Weight=-Weight WHERE Weight<0;"
00738             "INSERT INTO LensHFOVTable(Lens, Focallength, HFOV, Weight) "
00739               "SELECT Lens, Focallength, SUM(HFOV*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM LensHFOVTable GROUP By Lens, Focallength;"
00740             "DELETE FROM LensHFOVTable WHERE Weight>=0;"
00741             "UPDATE LensHFOVTable SET Weight=-Weight WHERE Weight<0;"
00742             "INSERT INTO TCATable(Lens, Focallength, ra, rb, rc, rd, ba, bb, bc, bd, Weight) "
00743               "SELECT Lens, Focallength, SUM(ra*Weight)/SUM(Weight), SUM(rb*Weight)/SUM(Weight), SUM(rc*Weight)/SUM(Weight), SUM(rd*Weight)/SUM(Weight), SUM(ba*Weight)/SUM(Weight), SUM(bb*Weight)/SUM(Weight), SUM(bc*Weight)/SUM(Weight), SUM(bd*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM TCATable GROUP By Lens, Focallength;"
00744             "DELETE FROM TCATable WHERE Weight>=0;"
00745             "UPDATE TCATable SET Weight=-Weight WHERE Weight<0;"
00746             "INSERT INTO VignettingTable(Lens, Focallength, Aperture, Distance, Vb, Vc, Vd, Weight) "
00747               "SELECT Lens, Focallength, Aperture, Distance, SUM(Vb*Weight)/SUM(Weight), SUM(Vc*Weight)/SUM(Weight), SUM(Vd*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM VignettingTable GROUP By Lens, Focallength, Aperture, Distance;"
00748             "DELETE FROM VignettingTable WHERE Weight>=0;"
00749             "UPDATE VignettingTable SET Weight=-Weight WHERE Weight<0;"
00750             "INSERT INTO EMORTable(Maker, Model, ISO, Ra, Rb, Rc, Rd, Re, Weight) "
00751             "SELECT Maker, Model, ISO, SUM(Ra*Weight)/SUM(Weight), SUM(Rb*Weight)/SUM(Weight), SUM(Rc*Weight)/SUM(Weight), SUM(Rd*Weight)/SUM(Weight), SUM(Re*Weight)/SUM(Weight), SUM(Weight*Weight)/SUM(Weight)*-1 FROM EMORTable GROUP By Maker, Model, ISO;"
00752             "DELETE FROM EMORTable WHERE Weight>=0;"
00753             "UPDATE EMORTable SET Weight=-Weight WHERE Weight<0;",
00754             NULL, NULL, NULL);
00755         EndTransaction();
00756         return sqlite3_exec(m_db, "VACUUM;", NULL, NULL, NULL) == SQLITE_OK;
00757     };
00758     // remove lens from all tables
00759     bool RemoveLens(const std::string& lensname)
00760     {
00761         if (m_db == NULL)
00762         {
00763             return false;
00764         };
00765         BeginTransaction();
00766         bool result = RemoveLensFromTable("LensProjectionTable", lensname);
00767         result &= RemoveLensFromTable("LensHFOVTable", lensname);
00768         result &= RemoveLensFromTable("LensCropTable", lensname);
00769         result &= RemoveLensFromTable("DistortionTable", lensname);
00770         result &= RemoveLensFromTable("VignettingTable", lensname);
00771         result &= RemoveLensFromTable("TCATable", lensname);
00772         EndTransaction();
00773         return result;
00774     };
00775     // remove camera from database
00776     bool RemoveCamera(const std::string& maker, const std::string& model)
00777     {
00778         if (m_db == NULL)
00779         {
00780             return false;
00781         };
00782         BeginTransaction();
00783         bool result = RemoveCameraFromTable("CameraCropTable", maker, model);
00784         result &= RemoveCameraFromTable("EMORTable", maker, model);
00785         EndTransaction();
00786         return result;
00787     };
00788     // export to file
00789     bool ExportToFile(const std::string& filename)
00790     {
00791         if (m_db == NULL)
00792         {
00793             return false;
00794         };
00795         CleanUp();
00796         std::ofstream output(filename.c_str());
00797         if (output.is_open())
00798         {
00799             output << "TABLE=CameraCropTable" << std::endl
00800                 << "COLUMNS=Maker;Model;Cropfactor" << std::endl;
00801             OutputSQLToStream("SELECT Maker, Model, Cropfactor FROM CameraCropTable;", output);
00802             output << "ENDTABLE" << std::endl
00803                 << "TABLE=LensProjectionTable" << std::endl
00804                 << "COLUMNS=Lens;Projection" << std::endl;
00805             OutputSQLToStream("SELECT Lens, Projection FROM LensProjectionTable;", output);
00806             output << "ENDTABLE" << std::endl
00807                 << "TABLE=LensHFOVTable" << std::endl
00808                 << "COLUMNS=Lens;Focallength;HFOV;Weight" << std::endl;
00809             OutputSQLToStream("SELECT Lens, Focallength, HFOV, Weight FROM LensHFOVTable;", output);
00810             output << "ENDTABLE" << std::endl
00811                 << "TABLE=LensCropTable" << std::endl
00812                 << "COLUMNS=Lens;Focallength;Width;Height;CropLeft;CropRight;CropTop;CropBottom" << std::endl;
00813             OutputSQLToStream("SELECT Lens, Focallength, Width, Height, CropLeft, CropRight, CropTop, CropBottom FROM TABLE LensCropTable;", output);
00814             output << "ENDTABLE" << std::endl
00815                 << "TABLE=DistortionTable" << std::endl
00816                 << "COLUMNS=Lens;Focallength;a;b;c;Weight" << std::endl;
00817             OutputSQLToStream("SELECT Lens, Focallength, a, b, c, Weight FROM DistortionTable;", output);
00818             output << "ENDTABLE" << std::endl
00819                 << "TABLE=VignettingTable" << std::endl
00820                 << "COLUMNS=Lens;Focallength;Aperture;Distance;Vb;Vc;Vd;Weight" << std::endl;
00821             OutputSQLToStream("SELECT Lens, Focallength, Aperture, Distance, Vb, Vc, Vd, Weight FROM VignettingTable;", output);
00822             output << "ENDTABLE" << std::endl
00823                 << "TABLE=TCATable" << std::endl
00824                 << "COLUMNS=Lens;Focallength;ra;rb;rc;rd;ba;bb;bc;bd;Weight" << std::endl;
00825             OutputSQLToStream("SELECT Lens, Focallength, ra, rb, rc, rd, ba, bb, bc, bd, Weight FROM TCATable;", output);
00826             output << "ENDTABLE" << std::endl
00827                 << "TABLE=EMORTable" << std::endl
00828                 << "COLUMNS=Maker;Model;ISO;Ra;Rb;Rc;Rd;Re;Weight" << std::endl;
00829             OutputSQLToStream("SELECT Maker, Model, ISO, Ra, Rb, Rc, Rd, Re, Weight FROM EMORTable;", output);
00830             output << "ENDTABLE" << std::endl;
00831             output.close();
00832             return true;
00833         }
00834         else
00835         {
00836             std::cerr << "Could not open file \"" << filename << "\"." << std::endl;
00837             return false;
00838         };
00839     };
00840     // import data from external file 
00841     bool ImportFromFile(const std::string& filename)
00842     {
00843         if (m_db == NULL)
00844         {
00845             return false;
00846         };
00847         std::ifstream input(filename);
00848         if (input.is_open())
00849         {
00850             while (!input.eof())
00851             {
00852                 std::string line;
00853                 std::getline(input, line);
00854                 if (line.empty())
00855                 {
00856                     continue;
00857                 };
00858                 if (line.compare(0, 6, "TABLE=") == 0)
00859                 {
00860                     std::vector<std::string> substring = hugin_utils::SplitString(line, "=");
00861                     if (substring.size() == 2)
00862                     {
00863                         if (substring[1] == "CameraCropTable")
00864                         {
00865                             std::cout << "\tImporting CameraCropTable..." << std::endl;
00866                             if (!ImportCropFactor(input))
00867                             {
00868                                 input.close();
00869                                 std::cerr << "Error in input file." << std::endl;
00870                                 return false;
00871                             };
00872                         }
00873                         else
00874                         {
00875                             if (substring[1] == "LensProjectionTable")
00876                             {
00877                                 std::cout << "\tImporting LensProjectionTable..." << std::endl;
00878                                 if (!ImportProjection(input))
00879                                 {
00880                                     input.close();
00881                                     std::cerr << "Error in input file." << std::endl;
00882                                     return false;
00883                                 };
00884                             }
00885                             else
00886                             {
00887                                 if (substring[1] == "LensHFOVTable")
00888                                 {
00889                                     std::cout << "\tImporting LensHFOVTable..." << std::endl;
00890                                     if (!ImportHFOV(input))
00891                                     {
00892                                         input.close();
00893                                         std::cerr << "Error in input file." << std::endl;
00894                                         return false;
00895                                     };
00896                                 }
00897                                 else
00898                                 {
00899                                     if (substring[1] == "LensCropTable")
00900                                     {
00901                                         std::cout << "\tImporting LensCropTable..." << std::endl;
00902                                         if (!ImportLensCrop(input))
00903                                         {
00904                                             input.close();
00905                                             std::cerr << "Error in input file." << std::endl;
00906                                             return false;
00907                                         };
00908                                     }
00909                                     else
00910                                     {
00911                                         if (substring[1] == "DistortionTable")
00912                                         {
00913                                             std::cout << "\tImporting DistortionTable..." << std::endl;
00914                                             if (!ImportDistortion(input))
00915                                             {
00916                                                 input.close();
00917                                                 std::cerr << "Error in input file." << std::endl;
00918                                                 return false;
00919                                             };
00920                                         }
00921                                         else
00922                                         {
00923                                             if (substring[1] == "VignettingTable")
00924                                             {
00925                                                 std::cout << "\tImporting VignettingTable..." << std::endl;
00926                                                 if (!ImportVignetting(input))
00927                                                 {
00928                                                     input.close();
00929                                                     std::cerr << "Error in input file." << std::endl;
00930                                                     return false;
00931                                                 };
00932                                             }
00933                                             else
00934                                             {
00935                                                 if (substring[1] == "TCATable")
00936                                                 {
00937                                                     std::cout << "\tImporting TCATable..." << std::endl;
00938                                                     if (!ImportTCA(input))
00939                                                     {
00940                                                         input.close();
00941                                                         std::cerr << "Error in input file." << std::endl;
00942                                                         return false;
00943                                                     };
00944                                                 }
00945                                                 else
00946                                                 {
00947                                                     if (substring[1] == "EMORTable")
00948                                                     {
00949                                                         std::cout << "\tImporting EMORTable..." << std::endl;
00950                                                         if (!ImportEMOR(input))
00951                                                         {
00952                                                             input.close();
00953                                                             std::cerr << "Error in input file." << std::endl;
00954                                                             return false;
00955                                                         };
00956                                                     }
00957                                                     else
00958                                                     {
00959                                                         input.close();
00960                                                         std::cerr << "Error in input file (Unknown table \"" << substring[1] << "\")." << std::endl;
00961                                                         return false;
00962                                                     };
00963                                                 };
00964                                             };
00965                                         };
00966                                     };
00967                                 };
00968                             };
00969                         };
00970                     }
00971                     else
00972                     {
00973                         std::cerr << "Error in input file (Could not parse table name)." << std::endl;
00974                         input.close();
00975                         return false;
00976                     };
00977                 }
00978                 else
00979                 {
00980                     std::cerr << "Error in input file (Could not find TABLE section)." << std::endl;
00981                     input.close();
00982                     return false;
00983                 };
00984             };
00985             input.close();
00986             CleanUp();
00987             return true;
00988         }
00989         else
00990         {
00991             std::cerr << "Could not open file \"" << filename << "\"." << std::endl;
00992             return false;
00993         };
00994     };
00995 private:
00996     // helper functions for BEGIN/COMMIT TRANSACTION
00997     void BeginTransaction()
00998     {
00999         if (!m_runningTransaction)
01000         {
01001             m_runningTransaction = (sqlite3_exec(m_db, "BEGIN TRANSACTION;", NULL, NULL, NULL) == SQLITE_OK);
01002         };
01003     };
01004     void EndTransaction()
01005     {
01006         if (m_runningTransaction)
01007         {
01008             sqlite3_exec(m_db, "COMMIT TRANSACTION;", NULL, NULL, NULL);
01009             m_runningTransaction = false;
01010         };
01011     };
01012 
01013     // removes the given lens from the selected table
01014     bool RemoveLensFromTable(const std::string& table, const std::string& lens)
01015     {
01016         sqlite3_stmt *statement;
01017         const char *tail;
01018         int returnValue = 0;
01019         std::string sqlStatement("DELETE FROM ");
01020         sqlStatement.append(table);
01021         sqlStatement.append(" WHERE Lens=?;");
01022         if (sqlite3_prepare_v2(m_db, sqlStatement.c_str(), -1, &statement, &tail) == SQLITE_OK)
01023         {
01024             sqlite3_bind_text(statement, 1, lens.c_str(), -1, NULL);
01025             returnValue = sqlite3_step(statement);
01026         };
01027         sqlite3_finalize(statement);
01028         return returnValue == SQLITE_DONE;
01029     };
01030     // remove given camera from selected table
01031     bool RemoveCameraFromTable(const std::string& table, const std::string& maker, const std::string& model)
01032     {
01033         sqlite3_stmt *statement;
01034         const char *tail;
01035         int returnValue = 0;
01036         std::string sqlStatement("DELETE FROM ");
01037         sqlStatement.append(table);
01038         sqlStatement.append(" WHERE Maker=?1 AND Model=?2;");
01039         if (sqlite3_prepare_v2(m_db, sqlStatement.c_str(), -1, &statement, &tail) == SQLITE_OK)
01040         {
01041             sqlite3_bind_text(statement, 1, maker.c_str(), -1, NULL);
01042             sqlite3_bind_text(statement, 2, model.c_str(), -1, NULL);
01043             returnValue = sqlite3_step(statement);
01044         };
01045         sqlite3_finalize(statement);
01046         return returnValue == SQLITE_DONE;
01047     };
01048     // write result of sql statement to stream, the columns are separated by ;
01049     void OutputSQLToStream(const std::string& sqlstatement, std::ostream& stream)
01050     {
01051         sqlite3_stmt *statement;
01052         const char *tail;
01053         if (sqlite3_prepare_v2(m_db, sqlstatement.c_str(), -1, &statement, &tail) == SQLITE_OK)
01054         {
01055             while (sqlite3_step(statement) == SQLITE_ROW)
01056             {
01057                 const int count = sqlite3_column_count(statement);
01058                 if (count > 0)
01059                 {
01060                     for (int i = 0; i < count; ++i)
01061                     {
01062                         stream << sqlite3_column_text(statement, i);
01063                         if (i + 1 < count)
01064                         {
01065                             stream << ";";
01066                         };
01067                     };
01068                 };
01069                 stream << std::endl;
01070             };
01071         };
01072         sqlite3_finalize(statement);
01073     }
01074     // import cropfactors from stream
01075     bool ImportCropFactor(std::istream& input)
01076     {
01077         std::string s;
01078         std::getline(input, s);
01079         // first line should contains the column list
01080         if (s.compare(0, 8, "COLUMNS=") != 0)
01081         {
01082             return false;
01083         };
01084         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01085         size_t indexMaker = -1;
01086         size_t indexModel = -1;
01087         size_t indexCropfactor = -1;
01088         for (size_t i = 0; i < columns.size(); ++i)
01089         {
01090             if (columns[i] == "Maker")
01091             {
01092                 indexMaker = i;
01093             };
01094             if (columns[i] == "Model")
01095             {
01096                 indexModel = i;
01097             };
01098             if (columns[i] == "Cropfactor")
01099             {
01100                 indexCropfactor = i;
01101             };
01102         };
01103         if (indexMaker == -1)
01104         {
01105             std::cerr << "ERROR: Missing column \"Maker\"." << std::endl;
01106             return false;
01107         };
01108         if (indexModel == -1)
01109         {
01110             std::cerr << "ERROR: Missing column \"Model\"." << std::endl;
01111             return false;
01112         };
01113         if (indexCropfactor == -1)
01114         {
01115             std::cerr << "ERROR: Missing column \"Cropfactor\"." << std::endl;
01116             return false;
01117         };
01118         if (input.eof())
01119         {
01120             return false;
01121         };
01122         std::getline(input, s);
01123         while (!input.eof())
01124         {
01125             if (s == "ENDTABLE")
01126             {
01127                 return true;
01128             }
01129             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01130             if (items.size() == columns.size())
01131             {
01132                 //ignore lines with not matching count of items
01133                 double cropfactor;
01134                 if (hugin_utils::stringToDouble(items[indexCropfactor], cropfactor))
01135                 {
01136                     SaveCropFactor(items[indexMaker], items[indexModel], cropfactor);
01137                 };
01138             };
01139             std::getline(input, s);
01140         };
01141         return false;
01142     };
01143     // import projection settings from stream
01144     bool ImportProjection(std::istream& input)
01145     {
01146         std::string s;
01147         std::getline(input, s);
01148         // first line should contains the column list
01149         if (s.compare(0, 8, "COLUMNS=") != 0)
01150         {
01151             return false;
01152         };
01153         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01154         size_t indexLens = -1;
01155         size_t indexProjection = -1;
01156         for (size_t i = 0; i < columns.size(); ++i)
01157         {
01158             if (columns[i] == "Lens")
01159             {
01160                 indexLens = i;
01161             };
01162             if (columns[i] == "Projection")
01163             {
01164                 indexProjection = i;
01165             };
01166         };
01167         if (indexLens == -1)
01168         {
01169             std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
01170             return false;
01171         };
01172         if (indexProjection == -1)
01173         {
01174             std::cerr << "ERROR: Missing column \"Projection\"." << std::endl;
01175             return false;
01176         };
01177         if (input.eof())
01178         {
01179             return false;
01180         };
01181         std::getline(input, s);
01182         while (!input.eof())
01183         {
01184             if (s == "ENDTABLE")
01185             {
01186                 return true;
01187             }
01188             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01189             if (items.size() == columns.size())
01190             {
01191                 //ignore lines with not matching count of items
01192                 int projection;
01193                 if (hugin_utils::stringToInt(items[indexProjection], projection))
01194                 {
01195                     SaveLensProjection(items[indexLens], projection);
01196                 };
01197             };
01198             std::getline(input, s);
01199         };
01200         return false;
01201     };
01202     // import hfov values from stream
01203     bool ImportHFOV(std::istream& input)
01204     {
01205         std::string s;
01206         std::getline(input, s);
01207         // first line should contains the column list
01208         if (s.compare(0, 8, "COLUMNS=") != 0)
01209         {
01210             return false;
01211         };
01212         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01213         size_t indexLens = -1;
01214         size_t indexFocallength = -1;
01215         size_t indexHFOV = -1;
01216         size_t indexWeight = -1;
01217         for (size_t i = 0; i < columns.size(); ++i)
01218         {
01219             if (columns[i] == "Lens")
01220             {
01221                 indexLens = i;
01222             };
01223             if (columns[i] == "Focallength")
01224             {
01225                 indexFocallength = i;
01226             };
01227             if (columns[i] == "HFOV")
01228             {
01229                 indexHFOV = i;
01230             };
01231             if (columns[i] == "Weight")
01232             {
01233                 indexWeight = i;
01234             };
01235         };
01236         if (indexLens == -1)
01237         {
01238             std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
01239             return false;
01240         };
01241         if (indexFocallength == -1)
01242         {
01243             std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
01244             return false;
01245         };
01246         if (indexHFOV == -1)
01247         {
01248             std::cerr << "ERROR: Missing column \"HFOV\"." << std::endl;
01249             return false;
01250         };
01251         if (indexWeight == -1)
01252         {
01253             std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
01254             return false;
01255         };
01256         if (input.eof())
01257         {
01258             return false;
01259         };
01260         std::getline(input, s);
01261         while (!input.eof())
01262         {
01263             if (s == "ENDTABLE")
01264             {
01265                 return true;
01266             }
01267             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01268             if (items.size() == columns.size())
01269             {
01270                 //ignore lines with not matching count of items
01271                 double focallength;
01272                 double hfov;
01273                 int weight;
01274                 bool valid = hugin_utils::stringToDouble(items[indexFocallength], focallength);
01275                 valid &= hugin_utils::stringToDouble(items[indexHFOV], hfov);
01276                 valid &= hugin_utils::stringToInt(items[indexWeight], weight);
01277                 if (valid)
01278                 {
01279                     SaveHFOV(items[indexLens], focallength, hfov, weight);
01280                 };
01281             };
01282             std::getline(input, s);
01283         };
01284         return false;
01285     };
01286     // import crop values from stream
01287     bool ImportLensCrop(std::istream& input)
01288     {
01289         std::string s;
01290         std::getline(input, s);
01291         // first line should contains the column list
01292         if (s.compare(0, 8, "COLUMNS=") != 0)
01293         {
01294             return false;
01295         };
01296         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01297         size_t indexLens = -1;
01298         size_t indexFocallength = -1;
01299         size_t indexWidth = -1;
01300         size_t indexHeight = -1;
01301         size_t indexCropLeft = -1;
01302         size_t indexCropRight = -1;
01303         size_t indexCropTop = -1;
01304         size_t indexCropBottom = -1;
01305         for (size_t i = 0; i < columns.size(); ++i)
01306         {
01307             if (columns[i] == "Lens")
01308             {
01309                 indexLens = i;
01310             };
01311             if (columns[i] == "Focallength")
01312             {
01313                 indexFocallength = i;
01314             };
01315             if (columns[i] == "Width")
01316             {
01317                 indexWidth = i;
01318             };
01319             if (columns[i] == "Height")
01320             {
01321                 indexHeight = i;
01322             };
01323             if (columns[i] == "CropLeft")
01324             {
01325                 indexCropLeft = i;
01326             };
01327             if (columns[i] == "CropRight")
01328             {
01329                 indexCropRight = i;
01330             };
01331             if (columns[i] == "CropTop")
01332             {
01333                 indexCropTop = i;
01334             };
01335             if (columns[i] == "CropBottom")
01336             {
01337                 indexCropBottom = i;
01338             };
01339         };
01340         if (indexLens == -1)
01341         {
01342             std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
01343             return false;
01344         };
01345         if (indexFocallength == -1)
01346         {
01347             std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
01348             return false;
01349         };
01350         if (indexWidth == -1)
01351         {
01352             std::cerr << "ERROR: Missing column \"Width\"." << std::endl;
01353             return false;
01354         };
01355         if (indexHeight == -1)
01356         {
01357             std::cerr << "ERROR: Missing column \"Height\"." << std::endl;
01358             return false;
01359         };
01360         if (indexCropLeft == -1)
01361         {
01362             std::cerr << "ERROR: Missing column \"CropLeft\"." << std::endl;
01363             return false;
01364         };
01365         if (indexCropRight == -1)
01366         {
01367             std::cerr << "ERROR: Missing column \"CropRight\"." << std::endl;
01368             return false;
01369         };
01370         if (indexCropTop == -1)
01371         {
01372             std::cerr << "ERROR: Missing column \"CropTop\"." << std::endl;
01373             return false;
01374         };
01375         if (indexCropBottom == -1)
01376         {
01377             std::cerr << "ERROR: Missing column \"CropBottom\"." << std::endl;
01378             return false;
01379         };
01380         if (input.eof())
01381         {
01382             return false;
01383         };
01384         std::getline(input, s);
01385         while (!input.eof())
01386         {
01387             if (s == "ENDTABLE")
01388             {
01389                 return true;
01390             }
01391             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01392             if (items.size() == columns.size())
01393             {
01394                 //ignore lines with not matching count of items
01395                 double focallength;
01396                 int width, height, cropLeft, cropRight, cropTop, cropBottom;
01397                 bool valid = hugin_utils::stringToDouble(items[indexFocallength], focallength);
01398                 valid &= hugin_utils::stringToInt(items[indexWidth], width);
01399                 valid &= hugin_utils::stringToInt(items[indexHeight], height);
01400                 valid &= hugin_utils::stringToInt(items[indexCropLeft], cropLeft);
01401                 valid &= hugin_utils::stringToInt(items[indexCropRight], cropRight);
01402                 valid &= hugin_utils::stringToInt(items[indexCropTop], cropTop);
01403                 valid &= hugin_utils::stringToInt(items[indexCropBottom], cropBottom);
01404                 if (valid)
01405                 {
01406                     SaveLensCrop(items[indexLens], focallength, width, height, cropLeft, cropRight, cropTop, cropBottom);
01407                 };
01408             };
01409             std::getline(input, s);
01410         };
01411         return false;
01412     };
01413     // import distortion values from stream
01414     bool ImportDistortion(std::istream& input)
01415     {
01416         std::string s;
01417         std::getline(input, s);
01418         // first line should contains the column list
01419         if (s.compare(0, 8, "COLUMNS=") != 0)
01420         {
01421             return false;
01422         };
01423         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01424         size_t indexLens = -1;
01425         size_t indexFocallength = -1;
01426         size_t indexA = -1;
01427         size_t indexB = -1;
01428         size_t indexC = -1;
01429         size_t indexWeight = -1;
01430         for (size_t i = 0; i < columns.size(); ++i)
01431         {
01432             if (columns[i] == "Lens")
01433             {
01434                 indexLens = i;
01435             };
01436             if (columns[i] == "Focallength")
01437             {
01438                 indexFocallength = i;
01439             };
01440             if (columns[i] == "a")
01441             {
01442                 indexA = i;
01443             };
01444             if (columns[i] == "b")
01445             {
01446                 indexB = i;
01447             };
01448             if (columns[i] == "c")
01449             {
01450                 indexC = i;
01451             };
01452             if (columns[i] == "Weight")
01453             {
01454                 indexWeight = i;
01455             };
01456         };
01457         if (indexLens == -1)
01458         {
01459             std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
01460             return false;
01461         };
01462         if (indexFocallength == -1)
01463         {
01464             std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
01465             return false;
01466         };
01467         if (indexA == -1)
01468         {
01469             std::cerr << "ERROR: Missing column \"a\"." << std::endl;
01470             return false;
01471         };
01472         if (indexB == -1)
01473         {
01474             std::cerr << "ERROR: Missing column \"b\"." << std::endl;
01475             return false;
01476         };
01477         if (indexC == -1)
01478         {
01479             std::cerr << "ERROR: Missing column \"c\"." << std::endl;
01480             return false;
01481         };
01482         if (indexWeight == -1)
01483         {
01484             std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
01485             return false;
01486         };
01487         if (input.eof())
01488         {
01489             return false;
01490         };
01491         std::getline(input, s);
01492         while (!input.eof())
01493         {
01494             if (s == "ENDTABLE")
01495             {
01496                 return true;
01497             }
01498             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01499             if (items.size() == columns.size())
01500             {
01501                 //ignore lines with not matching count of items
01502                 double focallength, a, b, c;
01503                 int weight;
01504                 bool valid = hugin_utils::stringToDouble(items[indexFocallength], focallength);
01505                 valid &= hugin_utils::stringToDouble(items[indexA], a);
01506                 valid &= hugin_utils::stringToDouble(items[indexB], b);
01507                 valid &= hugin_utils::stringToDouble(items[indexC], c);
01508                 valid &= hugin_utils::stringToInt(items[indexWeight], weight);
01509                 if (valid)
01510                 {
01511                     SaveDistortion(items[indexLens], focallength, a, b, c, weight);
01512                 };
01513             };
01514             std::getline(input, s);
01515         };
01516         return false;
01517     };
01518     // import vignetting values from stream
01519     bool ImportVignetting(std::istream& input)
01520     {
01521         std::string s;
01522         std::getline(input, s);
01523         // first line should contains the column list
01524         if (s.compare(0, 8, "COLUMNS=") != 0)
01525         {
01526             return false;
01527         };
01528         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01529         size_t indexLens = -1;
01530         size_t indexFocallength = -1;
01531         size_t indexAperture = -1;
01532         size_t indexDistance = -1;
01533         size_t indexVb = -1;
01534         size_t indexVc = -1;
01535         size_t indexVd = -1;
01536         size_t indexWeight = -1;
01537         for (size_t i = 0; i < columns.size(); ++i)
01538         {
01539             if (columns[i] == "Lens")
01540             {
01541                 indexLens = i;
01542             };
01543             if (columns[i] == "Focallength")
01544             {
01545                 indexFocallength = i;
01546             };
01547             if (columns[i] == "Aperture")
01548             {
01549                 indexAperture = i;
01550             };
01551             if (columns[i] == "Distance")
01552             {
01553                 indexDistance = i;
01554             };
01555             if (columns[i] == "Vb")
01556             {
01557                 indexVb = i;
01558             };
01559             if (columns[i] == "Vc")
01560             {
01561                 indexVc = i;
01562             };
01563             if (columns[i] == "Vd")
01564             {
01565                 indexVd = i;
01566             };
01567             if (columns[i] == "Weight")
01568             {
01569                 indexWeight = i;
01570             };
01571         };
01572         if (indexLens == -1)
01573         {
01574             std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
01575             return false;
01576         };
01577         if (indexFocallength == -1)
01578         {
01579             std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
01580             return false;
01581         };
01582         if (indexAperture == -1)
01583         {
01584             std::cerr << "ERROR: Missing column \"Aperture\"." << std::endl;
01585             return false;
01586         };
01587         if (indexDistance == -1)
01588         {
01589             std::cerr << "ERROR: Missing column \"Distance\"." << std::endl;
01590             return false;
01591         };
01592         if (indexVb == -1)
01593         {
01594             std::cerr << "ERROR: Missing column \"Vb\"." << std::endl;
01595             return false;
01596         };
01597         if (indexVc == -1)
01598         {
01599             std::cerr << "ERROR: Missing column \"Vc\"." << std::endl;
01600             return false;
01601         };
01602         if (indexVd == -1)
01603         {
01604             std::cerr << "ERROR: Missing column \"Vd\"." << std::endl;
01605             return false;
01606         };
01607         if (indexWeight == -1)
01608         {
01609             std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
01610             return false;
01611         };
01612         if (input.eof())
01613         {
01614             return false;
01615         };
01616         std::getline(input, s);
01617         while (!input.eof())
01618         {
01619             if (s == "ENDTABLE")
01620             {
01621                 return true;
01622             }
01623             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01624             if (items.size() == columns.size())
01625             {
01626                 //ignore lines with not matching count of items
01627                 double focallength, aperture, distance, Vb, Vc, Vd;
01628                 int weight;
01629                 bool valid = hugin_utils::stringToDouble(items[indexFocallength], focallength);
01630                 valid &= hugin_utils::stringToDouble(items[indexAperture], aperture);
01631                 valid &= hugin_utils::stringToDouble(items[indexDistance], distance);
01632                 valid &= hugin_utils::stringToDouble(items[indexVb], Vb);
01633                 valid &= hugin_utils::stringToDouble(items[indexVc], Vc);
01634                 valid &= hugin_utils::stringToDouble(items[indexVd], Vd);
01635                 valid &= hugin_utils::stringToInt(items[indexWeight], weight);
01636                 if (valid)
01637                 {
01638                     SaveVignetting(items[indexLens], focallength, aperture, distance, Vb, Vc, Vd, weight);
01639                 };
01640             };
01641             std::getline(input, s);
01642         };
01643         return false;
01644     };
01645     // import tca values from stream
01646     bool ImportTCA(std::istream& input)
01647     {
01648         std::string s;
01649         std::getline(input, s);
01650         // first line should contains the column list
01651         if (s.compare(0, 8, "COLUMNS=") != 0)
01652         {
01653             return false;
01654         };
01655         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01656         size_t indexLens = -1;
01657         size_t indexFocallength = -1;
01658         size_t indexRa = -1;
01659         size_t indexRb = -1;
01660         size_t indexRc = -1;
01661         size_t indexRd = -1;
01662         size_t indexBa = -1;
01663         size_t indexBb = -1;
01664         size_t indexBc = -1;
01665         size_t indexBd = -1;
01666         size_t indexWeight = -1;
01667         for (size_t i = 0; i < columns.size(); ++i)
01668         {
01669             if (columns[i] == "Lens")
01670             {
01671                 indexLens = i;
01672             };
01673             if (columns[i] == "Focallength")
01674             {
01675                 indexFocallength = i;
01676             };
01677             if (columns[i] == "ra")
01678             {
01679                 indexRa = i;
01680             };
01681             if (columns[i] == "rb")
01682             {
01683                 indexRb = i;
01684             };
01685             if (columns[i] == "rc")
01686             {
01687                 indexRc = i;
01688             };
01689             if (columns[i] == "rd")
01690             {
01691                 indexRd = i;
01692             };
01693             if (columns[i] == "ba")
01694             {
01695                 indexBa = i;
01696             };
01697             if (columns[i] == "bb")
01698             {
01699                 indexBb = i;
01700             };
01701             if (columns[i] == "bc")
01702             {
01703                 indexBc = i;
01704             };
01705             if (columns[i] == "bd")
01706             {
01707                 indexBd = i;
01708             };
01709             if (columns[i] == "Weight")
01710             {
01711                 indexWeight = i;
01712             };
01713         };
01714         if (indexLens == -1)
01715         {
01716             std::cerr << "ERROR: Missing column \"Lens\"." << std::endl;
01717             return false;
01718         };
01719         if (indexFocallength == -1)
01720         {
01721             std::cerr << "ERROR: Missing column \"Focallength\"." << std::endl;
01722             return false;
01723         };
01724         if (indexRa == -1)
01725         {
01726             std::cerr << "ERROR: Missing column \"ra\"." << std::endl;
01727             return false;
01728         };
01729         if (indexRb == -1)
01730         {
01731             std::cerr << "ERROR: Missing column \"rb\"." << std::endl;
01732             return false;
01733         };
01734         if (indexRc == -1)
01735         {
01736             std::cerr << "ERROR: Missing column \"rc\"." << std::endl;
01737             return false;
01738         };
01739         if (indexRd == -1)
01740         {
01741             std::cerr << "ERROR: Missing column \"rd\"." << std::endl;
01742             return false;
01743         };
01744         if (indexBa == -1)
01745         {
01746             std::cerr << "ERROR: Missing column \"ba\"." << std::endl;
01747             return false;
01748         };
01749         if (indexBb == -1)
01750         {
01751             std::cerr << "ERROR: Missing column \"bb\"." << std::endl;
01752             return false;
01753         };
01754         if (indexBc == -1)
01755         {
01756             std::cerr << "ERROR: Missing column \"bc\"." << std::endl;
01757             return false;
01758         };
01759         if (indexBd == -1)
01760         {
01761             std::cerr << "ERROR: Missing column \"bd\"." << std::endl;
01762             return false;
01763         };
01764         if (indexWeight == -1)
01765         {
01766             std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
01767             return false;
01768         };
01769         if (input.eof())
01770         {
01771             return false;
01772         };
01773         std::getline(input, s);
01774         while (!input.eof())
01775         {
01776             if (s == "ENDTABLE")
01777             {
01778                 return true;
01779             }
01780             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01781             if (items.size() == columns.size())
01782             {
01783                 //ignore lines with not matching count of items
01784                 double focallength, ra, rb, rc, rd, ba, bb, bc, bd;
01785                 int weight;
01786                 bool valid = hugin_utils::stringToDouble(items[indexFocallength], focallength);
01787                 valid &= hugin_utils::stringToDouble(items[indexRa], ra);
01788                 valid &= hugin_utils::stringToDouble(items[indexRb], rb);
01789                 valid &= hugin_utils::stringToDouble(items[indexRc], rc);
01790                 valid &= hugin_utils::stringToDouble(items[indexRd], rd);
01791                 valid &= hugin_utils::stringToDouble(items[indexBa], ba);
01792                 valid &= hugin_utils::stringToDouble(items[indexBb], bb);
01793                 valid &= hugin_utils::stringToDouble(items[indexBc], bc);
01794                 valid &= hugin_utils::stringToDouble(items[indexBd], bd);
01795                 valid &= hugin_utils::stringToInt(items[indexWeight], weight);
01796                 if (valid)
01797                 {
01798                     SaveTCAData(items[indexLens], focallength, ra, rb, rc, rd, ba, bb, bc, bd, weight);
01799                 };
01800             };
01801             std::getline(input, s);
01802         };
01803         return false;
01804     };
01805     // import emor values from stream
01806     bool ImportEMOR(std::istream& input)
01807     {
01808         std::string s;
01809         std::getline(input, s);
01810         // first line should contains the column list
01811         if (s.compare(0, 8, "COLUMNS=") != 0)
01812         {
01813             return false;
01814         };
01815         std::vector<std::string> columns = hugin_utils::SplitString(s.substr(8), ";");
01816         size_t indexMaker = -1;
01817         size_t indexModel = -1;
01818         size_t indexISO = -1;
01819         size_t indexRa = -1;
01820         size_t indexRb = -1;
01821         size_t indexRc = -1;
01822         size_t indexRd = -1;
01823         size_t indexRe = -1;
01824         size_t indexWeight = -1;
01825         for (size_t i = 0; i < columns.size(); ++i)
01826         {
01827             if (columns[i] == "Maker")
01828             {
01829                 indexMaker = i;
01830             };
01831             if (columns[i] == "Model")
01832             {
01833                 indexModel = i;
01834             };
01835             if (columns[i] == "ISO")
01836             {
01837                 indexISO = i;
01838             };
01839             if (columns[i] == "Ra")
01840             {
01841                 indexRa = i;
01842             };
01843             if (columns[i] == "Rb")
01844             {
01845                 indexRb = i;
01846             };
01847             if (columns[i] == "Rc")
01848             {
01849                 indexRc = i;
01850             };
01851             if (columns[i] == "Rd")
01852             {
01853                 indexRd = i;
01854             };
01855             if (columns[i] == "Re")
01856             {
01857                 indexRe = i;
01858             };
01859             if (columns[i] == "Weight")
01860             {
01861                 indexWeight = i;
01862             };
01863         };
01864         if (indexMaker == -1)
01865         {
01866             std::cerr << "ERROR: Missing column \"Maker\"." << std::endl;
01867             return false;
01868         };
01869         if (indexModel == -1)
01870         {
01871             std::cerr << "ERROR: Missing column \"Model\"." << std::endl;
01872             return false;
01873         };
01874         if (indexISO == -1)
01875         {
01876             std::cerr << "ERROR: Missing column \"ISO\"." << std::endl;
01877             return false;
01878         };
01879         if (indexRa == -1)
01880         {
01881             std::cerr << "ERROR: Missing column \"Ra\"." << std::endl;
01882             return false;
01883         };
01884         if (indexRb == -1)
01885         {
01886             std::cerr << "ERROR: Missing column \"Rb\"." << std::endl;
01887             return false;
01888         };
01889         if (indexRc == -1)
01890         {
01891             std::cerr << "ERROR: Missing column \"Rc\"." << std::endl;
01892             return false;
01893         };
01894         if (indexRd == -1)
01895         {
01896             std::cerr << "ERROR: Missing column \"Rd\"." << std::endl;
01897             return false;
01898         };
01899         if (indexRe == -1)
01900         {
01901             std::cerr << "ERROR: Missing column \"Re\"." << std::endl;
01902             return false;
01903         };
01904         if (indexWeight == -1)
01905         {
01906             std::cerr << "ERROR: Missing column \"Weight\"." << std::endl;
01907             return false;
01908         };
01909         if (input.eof())
01910         {
01911             return false;
01912         };
01913         std::getline(input, s);
01914         while (!input.eof())
01915         {
01916             if (s == "ENDTABLE")
01917             {
01918                 return true;
01919             }
01920             std::vector<std::string> items = hugin_utils::SplitString(s, ";");
01921             if (items.size() == columns.size())
01922             {
01923                 //ignore lines with not matching count of items
01924                 double Ra, Rb, Rc, Rd, Re;
01925                 int iso, weight;
01926                 bool valid = hugin_utils::stringToInt(items[indexISO], iso);
01927                 valid &= hugin_utils::stringToDouble(items[indexRa], Ra);
01928                 valid &= hugin_utils::stringToDouble(items[indexRb], Rb);
01929                 valid &= hugin_utils::stringToDouble(items[indexRc], Rc);
01930                 valid &= hugin_utils::stringToDouble(items[indexRd], Rd);
01931                 valid &= hugin_utils::stringToDouble(items[indexRe], Re);
01932                 valid &= hugin_utils::stringToInt(items[indexWeight], weight);
01933                 if (valid)
01934                 {
01935                     SaveEMoR(items[indexMaker], items[indexModel], iso, Ra, Rb, Rc, Rd, Re, weight);
01936                 };
01937             };
01938             std::getline(input, s);
01939         };
01940         return false;
01941     };
01942 
01943     std::string m_filename;
01944     sqlite3 *m_db;
01945     bool m_runningTransaction;
01946 };
01947 
01948 double InterpolateValue(double x, double x0, double y0, double x1, double y1)
01949 {
01950     if (fabs(x1 - x0) < 1e-4)
01951     {
01952         // prevent division through 0, should normally not happens
01953         return y0;
01954     };
01955     return y0 + (y1 - y0) * (x - x0) / (x1 - x0);
01956 };
01957 
01958 double InterpolateValueTriangle(double x, double y,
01959     double x1, double y1, double z1,
01960     double x2, double y2, double z2,
01961     double x3, double y3, double z3)
01962 {
01963     const double a = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
01964     if (fabs(a) < 1e-6)
01965     {
01966         // this should never happens
01967         return z1;
01968     };
01969     return z1 + ((x - x1) * ((z2 - z1) * (y3 - y1) - (y2 - y1) * (z3 - z1)) + (y - y1) * ((x2 - x1) * (z3 - z1) - (z2 - z1) * (x3 - x1))) / a;
01970 };
01971 
01972 LensDB::LensDB()
01973 {
01974     std::string filename = hugin_utils::GetUserAppDataDir();
01975     if (filename.length() == 0)
01976     {
01977         m_db = NULL;
01978     }
01979     else
01980     {
01981 #if WIN32
01982         filename.append("\\");
01983 #else
01984         filename.append("/");
01985 #endif
01986         filename.append("camlens.db");
01987         m_db = new LensDB::Database(filename);
01988         if (!m_db)
01989         {
01990             m_db = NULL;
01991         };
01992     };
01993 };
01994 
01995 LensDB::~LensDB()
01996 {
01997     if (m_db)
01998         delete m_db;
01999 };
02000 
02001 LensDB& LensDB::GetSingleton()
02002 {
02003     if(m_instance==NULL)
02004     {
02005         m_instance = new LensDB();
02006     };
02007     return *m_instance;
02008 };
02009 
02010 void LensDB::Clean()
02011 {
02012     if (m_instance != NULL)
02013     {
02014         delete m_instance;
02015     };
02016     m_instance = NULL;
02017 };
02018 
02019 std::string LensDB::GetDBFilename() const
02020 {
02021     if (m_db)
02022     {
02023         return m_db->GetDBFilename();
02024     }
02025     else
02026     {
02027         return std::string();
02028     };
02029 };
02030 
02031 bool LensDB::GetCropFactor(const std::string& maker, const std::string& model, double& cropFactor) const
02032 {
02033     if (m_db == NULL)
02034     {
02035         return false;
02036     };
02037     return m_db->GetCropFactor(maker, model, cropFactor);
02038 };
02039 
02040 bool LensDB::GetProjection(const std::string& lens, BaseSrcPanoImage::Projection& projection) const
02041 {
02042     if (m_db == NULL)
02043     {
02044         return false;
02045     };
02046     int proj;
02047     if (m_db->GetLensProjection(lens, proj))
02048     {
02049         projection = static_cast<BaseSrcPanoImage::Projection>(proj);
02050         return true;
02051     }
02052     else
02053     {
02054         return false;
02055     };
02056 };
02057 
02058 inline int fsign(double a)
02059 {
02060     return (a > 0) ? 1 : ((a < 0) ? -1 : 0);
02061 }
02062 
02064 bool IsFocallengthNearRange(const double focal, const double limit1, const double limit2, const double tol)
02065 {
02066     if (fsign(focal - limit1) != fsign(focal - limit2))
02067     {
02068         return true;
02069     };
02070     return fabs(focal - limit1) < tol * focal;
02071 }
02072 
02073 bool LensDB::GetCrop(const std::string& lens, const double focal, const vigra::Size2D& imageSize, vigra::Rect2D& cropRect) const
02074 {
02075     if(m_db == NULL)
02076     {
02077         return false;
02078     };
02079     std::vector<Database::CropData> cropData;
02080     if (!m_db->GetLensCrop(lens, focal, imageSize.width() , imageSize.height(), cropData))
02081     {
02082         return false;
02083     };
02084     int left, right, top, bottom;
02085     if (cropData.size() == 1)
02086     {
02087         // only one entry found
02088         // check focal length
02089         if (fabs(cropData[0].focallength - focal) < 0.075f * focal)
02090         {
02091             // focal length matches
02092             left = cropData[0].left;
02093             right = cropData[0].right;
02094             top = cropData[0].top;
02095             bottom = cropData[0].bottom;
02096         }
02097         else
02098         {
02099             // if focal length does not match we ignore crop 
02100             return false;
02101         }
02102     }
02103     else
02104     {
02105         if (!IsFocallengthNearRange(focal, cropData[0].focallength, cropData[1].focallength, 0.15f))
02106         {
02107             return false;
02108         };
02109         left = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].left, cropData[1].focallength, cropData[1].left));
02110         right = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].right, cropData[1].focallength, cropData[1].right));
02111         top = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].top, cropData[1].focallength, cropData[1].top));
02112         bottom = hugin_utils::roundi(InterpolateValue(focal, cropData[0].focallength, cropData[0].bottom, cropData[1].focallength, cropData[1].bottom));
02113     };
02114     cropRect.setUpperLeft(vigra::Point2D(left, top));
02115     cropRect.setLowerRight(vigra::Point2D(right, bottom));
02116     return true;
02117 };
02118 
02119 bool LensDB::GetFov(const std::string& lens, const double focal, double& fov) const
02120 {
02121     if (m_db == NULL)
02122     {
02123         return false;
02124     };
02125     std::vector<Database::HFOVData> hfovdata;
02126     if (!m_db->GetHFOV(lens, focal, hfovdata))
02127     {
02128         return false;
02129     };
02130     fov = 0;
02131     if (hfovdata.size() == 1)
02132     {
02133         // only one entry found
02134         // check focal length
02135         if (fabs(hfovdata[0].focallength - focal) <= 0.075f * focal)
02136         {
02137             // focal length matches
02138             fov = hfovdata[0].HFOV;
02139         }
02140         else
02141         {
02142             // if focal length does not match we ignore HFOV 
02143             return false;
02144         }
02145     }
02146     else
02147     {
02148         if (!IsFocallengthNearRange(focal, hfovdata[0].focallength, hfovdata[1].focallength, 0.15f))
02149         {
02150             // difference to nearest point too big, ignoring
02151             return false;
02152         }
02153         fov = InterpolateValue(focal, hfovdata[0].focallength, hfovdata[0].HFOV, hfovdata[1].focallength, hfovdata[1].HFOV);
02154         if (fov < 0.1)
02155         {
02156             fov = 0;
02157         };
02158     };
02159     return (fov > 0);
02160 };
02161 
02162 bool LensDB::GetDistortion(const std::string& lens, const double focal, std::vector<double>& distortion) const
02163 {
02164     distortion.clear();
02165     if (m_db == NULL)
02166     {
02167         return false;
02168     };
02169     std::vector<Database::Distortiondata> distdata;
02170     if (!m_db->GetDistortionData(lens, focal, distdata))
02171     {
02172         return false;
02173     };
02174     if (distdata.size() == 1)
02175     {
02176         // only one entry found
02177         // check focal length
02178         if (fabs(distdata[0].focallength - focal) <= 0.075f * focal)
02179         {
02180             distortion.push_back(distdata[0].a);
02181             distortion.push_back(distdata[0].b);
02182             distortion.push_back(distdata[0].c);
02183             return true;
02184         }
02185         else
02186         {
02187             std::cout << "Invalid focallength" << std::endl;
02188             return false;
02189         };
02190     }
02191     else
02192     {
02193         if (!IsFocallengthNearRange(focal, distdata[0].focallength, distdata[1].focallength, 0.15f))
02194         {
02195             // difference to nearest point too big, ignoring
02196             return false;
02197         }
02198         distortion.push_back(InterpolateValue(focal, distdata[0].focallength, distdata[0].a, distdata[1].focallength, distdata[1].a));
02199         distortion.push_back(InterpolateValue(focal, distdata[0].focallength, distdata[0].b, distdata[1].focallength, distdata[1].b));
02200         distortion.push_back(InterpolateValue(focal, distdata[0].focallength, distdata[0].c, distdata[1].focallength, distdata[1].c));
02201         return true;
02202     };
02203 };
02204 
02205 bool LensDB::GetVignetting(const std::string& lens, const double focal, const double aperture, const double distance, std::vector<double>& vignetting) const
02206 {
02207     vignetting.clear();
02208     if (m_db == NULL)
02209     {
02210         return false;
02211     };
02212     std::vector<Database::Vignettingdata> vigdata;
02213     if (!m_db->GetVignettingData(lens, focal, aperture, vigdata))
02214     {
02215         return false;
02216     };
02217     const bool unknownAperture = (fabs(aperture) < 0.001f);
02218     if (vigdata.size() == 1)
02219     {
02220         if ((fabs(vigdata[0].focallength - focal) <= 0.075f * focal) && (unknownAperture || fabs(vigdata[0].aperture - aperture) < 0.3f))
02221         {
02222             vignetting.push_back(1.0);
02223             vignetting.push_back(vigdata[0].Vb);
02224             vignetting.push_back(vigdata[0].Vc);
02225             vignetting.push_back(vigdata[0].Vd);
02226             return true;
02227         }
02228         else
02229         {
02230             return false;
02231         }
02232     }
02233     else
02234     {
02235         if (vigdata.size() == 2)
02236         {
02237             if (fabs(vigdata[0].focallength - vigdata[1].focallength) < 0.001f)
02238             {
02239                 // variant a: 2 datasets with same focal length
02240                 if (unknownAperture)
02241                 {
02242                     vignetting.push_back(1.0);
02243                     vignetting.push_back(vigdata[0].Vb);
02244                     vignetting.push_back(vigdata[0].Vc);
02245                     vignetting.push_back(vigdata[0].Vd);
02246                     return true;
02247                 }
02248                 else
02249                 {
02250                     if (vigdata[0].aperture - 0.3 <= aperture && aperture <= vigdata[1].aperture + 0.3)
02251                     {
02252                         vignetting.push_back(1.0);
02253                         vignetting.push_back(InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vb, vigdata[1].aperture, vigdata[1].Vb));
02254                         vignetting.push_back(InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vc, vigdata[1].aperture, vigdata[1].Vc));
02255                         vignetting.push_back(InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vd, vigdata[1].aperture, vigdata[1].Vd));
02256                         return true;
02257                     }
02258                     else
02259                     {
02260                         return false;
02261                     };
02262                 };
02263             }
02264             else
02265             {
02266                 // variant b: 2 datasets from different focal length
02267                 if (!IsFocallengthNearRange(focal, vigdata[0].focallength, vigdata[1].focallength, 0.15f))
02268                 {
02269                     return false;
02270                 };
02271                 const double interpolatedAperture = InterpolateValue(focal, vigdata[0].focallength, vigdata[0].aperture, vigdata[1].focallength, vigdata[1].aperture);
02272                 if (fabs(interpolatedAperture - aperture) < 0.3f || unknownAperture)
02273                 {
02274                     // return value only, if aperture matches the 2 found values
02275                     vignetting.push_back(1.0);
02276                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vb, vigdata[1].focallength, vigdata[1].Vb));
02277                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vc, vigdata[1].focallength, vigdata[1].Vc));
02278                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vd, vigdata[1].focallength, vigdata[1].Vd));
02279                     return true;
02280                 }
02281                 else
02282                 {
02283                     return false;
02284                 };
02285             };
02286         }
02287         else
02288         {
02289             if (vigdata.size() == 3)
02290             {
02291                 if (!IsFocallengthNearRange(focal, vigdata[0].focallength, vigdata[2].focallength, 0.15f))
02292                 {
02293                     return false;
02294                 };
02295                 vignetting.push_back(1.0);
02296                 vignetting.push_back(InterpolateValueTriangle(focal, aperture,
02297                     vigdata[0].focallength, vigdata[0].aperture, vigdata[0].Vb,
02298                     vigdata[1].focallength, vigdata[1].aperture, vigdata[1].Vb,
02299                     vigdata[2].focallength, vigdata[2].aperture, vigdata[2].Vb
02300                     ));
02301                 vignetting.push_back(InterpolateValueTriangle(focal, aperture,
02302                     vigdata[0].focallength, vigdata[0].aperture, vigdata[0].Vc,
02303                     vigdata[1].focallength, vigdata[1].aperture, vigdata[1].Vc,
02304                     vigdata[2].focallength, vigdata[2].aperture, vigdata[2].Vc
02305                     ));
02306                 vignetting.push_back(InterpolateValueTriangle(focal, aperture,
02307                     vigdata[0].focallength, vigdata[0].aperture, vigdata[0].Vd,
02308                     vigdata[1].focallength, vigdata[1].aperture, vigdata[1].Vd,
02309                     vigdata[2].focallength, vigdata[2].aperture, vigdata[2].Vd
02310                     ));
02311                 return true;
02312             }
02313             else
02314             {
02315                 // we have now 4 points for interpolation
02316                 if (!IsFocallengthNearRange(focal, vigdata[0].focallength, vigdata[2].focallength, 0.15f))
02317                 {
02318                     return false;
02319                 };
02320                 if (unknownAperture)
02321                 {
02322                     // unknown aperture, take smallest aperture
02323                     vignetting.push_back(1.0);
02324                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vb, vigdata[2].focallength, vigdata[2].Vb));
02325                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vc, vigdata[2].focallength, vigdata[2].Vc));
02326                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, vigdata[0].Vd, vigdata[2].focallength, vigdata[2].Vd));
02327                     return true;
02328                 }
02329                 else
02330                 {
02331                     // interpolate for each focal length to desired aperture
02332                     double Vb1, Vc1, Vd1, Vb2, Vc2, Vd2;
02333                     if (vigdata[0].aperture - 0.3 <= aperture && aperture <= vigdata[1].aperture + 0.3)
02334                     {
02335                         Vb1 = InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vb, vigdata[1].aperture, vigdata[1].Vb);
02336                         Vc1 = InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vc, vigdata[1].aperture, vigdata[1].Vc);
02337                         Vd1 = InterpolateValue(aperture, vigdata[0].aperture, vigdata[0].Vd, vigdata[1].aperture, vigdata[1].Vd);
02338                     }
02339                     else
02340                     {
02341                         return false;
02342                     };
02343                     if (vigdata[2].aperture - 0.3 <= aperture && aperture <= vigdata[3].aperture + 0.3)
02344                     {
02345                         Vb2 = InterpolateValue(aperture, vigdata[2].aperture, vigdata[2].Vb, vigdata[3].aperture, vigdata[3].Vb);
02346                         Vc2 = InterpolateValue(aperture, vigdata[2].aperture, vigdata[2].Vc, vigdata[3].aperture, vigdata[3].Vc);
02347                         Vd2 = InterpolateValue(aperture, vigdata[2].aperture, vigdata[2].Vd, vigdata[3].aperture, vigdata[3].Vd);
02348                     }
02349                     else
02350                     {
02351                         return false;
02352                     };
02353                     // now we have 2 values for the same aperture, but different focal length
02354                     // interpolate focal length
02355                     vignetting.push_back(1.0);
02356                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, Vb1, vigdata[2].focallength, Vb2));
02357                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, Vc1, vigdata[2].focallength, Vc2));
02358                     vignetting.push_back(InterpolateValue(focal, vigdata[0].focallength, Vd1, vigdata[2].focallength, Vd2));
02359                     return true;
02360                 };
02361             };
02362         };
02363     };
02364 };
02365 
02366 bool LensDB::GetTCA(const std::string& lens, const double focal, std::vector<double>& tca_red, std::vector<double>& tca_blue) const
02367 {
02368     tca_red.clear();
02369     tca_blue.clear();
02370     if (m_db == NULL)
02371     {
02372         return false;
02373     };
02374     std::vector<Database::TCAdata> tcadata;
02375     if (!m_db->GetTCAData(lens, focal, tcadata))
02376     {
02377         return false;
02378     };
02379     if (tcadata.size() == 1)
02380     {
02381         // only one entry found
02382         // check focal length
02383         if (fabs(tcadata[0].focallength - focal) <= 0.075f * focal)
02384         {
02385             tca_red.push_back(tcadata[0].ra);
02386             tca_red.push_back(tcadata[0].rb);
02387             tca_red.push_back(tcadata[0].rc);
02388             tca_red.push_back(tcadata[0].rd);
02389             tca_blue.push_back(tcadata[0].ba);
02390             tca_blue.push_back(tcadata[0].bb);
02391             tca_blue.push_back(tcadata[0].bc);
02392             tca_blue.push_back(tcadata[0].bd);
02393             return true;
02394         }
02395         else
02396         {
02397             return false;
02398         };
02399     }
02400     else
02401     {
02402         if (!IsFocallengthNearRange(focal, tcadata[0].focallength, tcadata[1].focallength, 0.15f))
02403         {
02404             // difference to nearest point too big, ignoring
02405             return false;
02406         };
02407         tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].ra, tcadata[1].focallength, tcadata[1].ra));
02408         tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].rb, tcadata[1].focallength, tcadata[1].rb));
02409         tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].rc, tcadata[1].focallength, tcadata[1].rc));
02410         tca_red.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].rd, tcadata[1].focallength, tcadata[1].rd));
02411         tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].ba, tcadata[1].focallength, tcadata[1].ba));
02412         tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].bb, tcadata[1].focallength, tcadata[1].bb));
02413         tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].bc, tcadata[1].focallength, tcadata[1].bc));
02414         tca_blue.push_back(InterpolateValue(focal, tcadata[0].focallength, tcadata[0].bd, tcadata[1].focallength, tcadata[1].bd));
02415         return true;
02416     };
02417 };
02418 
02419 bool LensDB::GetLensNames(const bool distortion, const bool vignetting, const bool tca, LensList& lensList) const
02420 {
02421     lensList.clear();
02422     if (m_db == NULL)
02423     {
02424         return false;
02425     };
02426     return m_db->GetLensNames(distortion, vignetting, tca, lensList);
02427 };
02428 
02429 bool LensDB::SaveCameraCrop(const std::string& maker, const std::string& model, const double cropfactor)
02430 {
02431     if (m_db == NULL)
02432     {
02433         return false;
02434     };
02435     return m_db->SaveCropFactor(maker, model, cropfactor);
02436 };
02437 
02438 bool LensDB::SaveEMoR(const std::string& maker, const std::string& model, const int iso, const std::vector<float>& emor, const int weight)
02439 {
02440     if (m_db == NULL || emor.size() != 5)
02441     {
02442         return false;
02443     };
02444     return m_db->SaveEMoR(maker, model, iso, emor[0], emor[1], emor[2], emor[3], emor[4], weight);
02445 };
02446 
02447 bool LensDB::SaveLensProjection(const std::string& lens, const BaseSrcPanoImage::Projection projection)
02448 {
02449     if (m_db == NULL)
02450     {
02451         return false;
02452     };
02453     return m_db->SaveLensProjection(lens, projection);
02454 };
02455 
02456 bool LensDB::SaveLensCrop(const std::string& lens, const double focal, const vigra::Size2D& imageSize, const vigra::Rect2D& cropRect)
02457 {
02458     if (m_db == NULL)
02459     {
02460         return false;
02461     };
02462     if (cropRect.isEmpty())
02463     {
02464         return m_db->RemoveLensCrop(lens, focal, imageSize.width(), imageSize.height());
02465     }
02466     else
02467     {
02468         return m_db->SaveLensCrop(lens, focal, imageSize.width(), imageSize.height(), cropRect.left(), cropRect.right(), cropRect.top(), cropRect.bottom());
02469     };
02470 };
02471 
02472 bool LensDB::SaveLensFov(const std::string& lens, const double focal, const double fov, const int weight)
02473 {
02474     if (m_db == NULL)
02475     {
02476         return false;
02477     };
02478     return m_db->SaveHFOV(lens, focal, fov, weight);
02479 };
02480 
02481 bool LensDB::SaveDistortion(const std::string& lens, const double focal, const std::vector<double>& distortion, const int weight)
02482 {
02483     if (m_db == NULL || distortion.size()!=4)
02484     {
02485         return false;
02486     };
02487     return m_db->SaveDistortion(lens, focal, distortion[0], distortion[1], distortion[2], weight);
02488 };
02489 
02490 bool LensDB::SaveVignetting(const std::string& lens, const double focal, const double aperture, const double distance, const std::vector<double>& vignetting, const int weight)
02491 {
02492     if (m_db == NULL || vignetting.size()!=4)
02493     {
02494         return false;
02495     };
02496     return m_db->SaveVignetting(lens, focal, aperture, distance, vignetting[1], vignetting[2], vignetting[3], weight);
02497 };
02498 
02499 bool LensDB::SaveTCA(const std::string& lens, const double focal, const std::vector<double>& tca_red, const std::vector<double>& tca_blue, const int weight)
02500 {
02501     if (m_db == NULL || tca_red.size()!=4 || tca_blue.size()!=4)
02502     {
02503         return false;
02504     };
02505     return m_db->SaveTCAData(lens, focal, tca_red[0], tca_red[1], tca_red[2], tca_red[3], tca_blue[0], tca_blue[1], tca_blue[2], tca_blue[3], weight);
02506 };
02507 
02508 bool LensDB::CleanUpDatabase()
02509 {
02510     if (m_db == NULL)
02511     {
02512         return false;
02513     };
02514     return m_db->CleanUp();
02515 };
02516 
02517 bool LensDB::RemoveLens(const std::string& lensname)
02518 {
02519     if (m_db == NULL)
02520     {
02521         return false;
02522     };
02523     return m_db->RemoveLens(lensname);
02524 };
02525 
02526 bool LensDB::RemoveCamera(const std::string& maker, const std::string& model)
02527 {
02528     if (m_db == NULL)
02529     {
02530         return false;
02531     };
02532     return m_db->RemoveCamera(maker, model);
02533 };
02534 
02535 bool LensDB::ExportToFile(const std::string& filename)
02536 {
02537     if (m_db == NULL)
02538     {
02539         return false;
02540     };
02541     return m_db->ExportToFile(filename);
02542 };
02543 
02544 bool LensDB::ImportFromFile(const std::string& filename)
02545 {
02546     if (m_db == NULL)
02547     {
02548         return false;
02549     };
02550     return m_db->ImportFromFile(filename);
02551 };
02552 
02553 bool SaveLensDataFromPano(const HuginBase::Panorama& pano)
02554 {
02555     if (pano.getNrOfImages() < 2)
02556     {
02557         // ignore project with only one image
02558         return false;
02559     };
02560     HuginBase::ConstStandardImageVariableGroups lenses(pano);
02561     if (lenses.getLenses().getNumberOfParts() == 1)
02562     {
02563         const SrcPanoImage& img0 = pano.getImage(0);
02564         LensDB& lensDB = LensDB::GetSingleton();
02565         const std::string camMaker = img0.getExifMake();
02566         const std::string camModel = img0.getExifModel();
02567         if (!camMaker.empty() && !camModel.empty())
02568         {
02569             if (img0.getExifCropFactor() < 0.1f)
02570             {
02571                 lensDB.SaveCameraCrop(camMaker, camModel, img0.getCropFactor());
02572             };
02573             // now check EMoR parameters
02574             const std::vector<float> emor=img0.getEMoRParams();
02575             if (emor.size() == 5)
02576             {
02577                 float sum = 0;
02578                 for (size_t i = 0; i < 5; ++i)
02579                 { 
02580                     sum += fabs(emor[i]);
02581                 };
02582                 if (sum>0.001)
02583                 {
02584                     lensDB.SaveEMoR(camMaker, camModel, img0.getExifISO(), emor);
02585                 };
02586             };
02587         };
02588         const std::string lensname = img0.getDBLensName();
02589         const double focal = img0.getExifFocalLength();
02590         if (!lensname.empty() && focal > 0)
02591         {
02592             bool success = lensDB.SaveLensProjection(lensname, img0.getProjection());
02593             if (img0.getCropMode() == BaseSrcPanoImage::NO_CROP)
02594             {
02595                 // pass empty Rect2D to remove crop information
02596                 success = success | lensDB.SaveLensCrop(lensname, focal, img0.getSize(), vigra::Rect2D(0, 0, 0, 0));
02597             }
02598             else
02599             {
02600                 const BaseSrcPanoImage::CropMode cropMode = img0.getCropMode();
02601                 const vigra::Rect2D cropRect = img0.getCropRect();
02602                 bool sameCrop = true;
02603                 for (size_t i = 1; i < pano.getNrOfImages() && sameCrop; ++i)
02604                 {
02605                     const SrcPanoImage& img = pano.getImage(i);
02606                     sameCrop = (img.getCropMode() == cropMode) && (img.getCropRect() == cropRect);
02607                 };
02608                 if (sameCrop)
02609                 {
02610                     success = success | lensDB.SaveLensCrop(lensname, focal, img0.getSize(), cropRect);
02611                 };
02612             };
02613             double min;
02614             double max;
02615             double mean;
02616             double var;
02617             // update cp errors
02618             CalculateCPStatisticsError::calcCtrlPntsErrorStats(pano, min, max, mean, var);
02619             if (mean < 15)
02620             {
02621                 // save hfov and distortion only if error is small enough
02622                 //@TODO add more robust check which takes also distribution of cp into account
02623                 // recalculate to default aspect ratio of 3:2
02624                 const double newFocallength = SrcPanoImage::calcFocalLength(img0.getProjection(), img0.getHFOV(), img0.getCropFactor(), img0.getSize());
02625                 const double newHFOV = SrcPanoImage::calcHFOV(img0.getProjection(), newFocallength, img0.getCropFactor(), vigra::Size2D(3000, 2000));
02626                 success = success | lensDB.SaveLensFov(lensname, focal, newHFOV);
02627                 const std::vector<double> dist = img0.getRadialDistortion();
02628                 if (dist.size() == 4)
02629                 {
02630                     // check if values are plausible
02631                     if (fabs(dist[0]) + fabs(dist[1]) + fabs(dist[2])>0.001 && 
02632                         fabs(dist[0] + dist[1] + dist[2]) < 0.1)
02633                     {
02634                         success = success | lensDB.SaveDistortion(lensname, focal, dist);
02635                     };
02636                 };
02637             };
02638             // check if aperture matches for all images
02639             bool sameAperture = true;
02640             for (size_t i = 1; i < pano.getNrOfImages() && sameAperture; ++i)
02641             {
02642                 sameAperture = fabs(pano.getImage(i).getExifAperture() - img0.getExifAperture()) < 0.05;
02643             }
02644             // save vignetting data only if all images were shoot with same aperture
02645             if (sameAperture)
02646             {
02647                 const std::vector<double> vigParam = img0.getRadialVigCorrCoeff();
02648                 if (vigParam.size() == 4)
02649                 {
02650                     // now check, if the vignetting parameter are plausible
02651                     const double sum = vigParam[0] + vigParam[1] + vigParam[2] + vigParam[3];
02652                     if (sum>0.5 && sum <= 1.01)
02653                     {
02654                         success = success | lensDB.SaveVignetting(lensname, focal, img0.getExifAperture(), img0.getExifDistance(), vigParam);
02655                     };
02656                 };
02657             };
02658             return success;
02659         }
02660         else
02661         {
02662             return false;
02663         };
02664     };
02665     return false;
02666 };
02667 
02668 } //namespace LensDB
02669 } //namespace HuginBase

Generated on 4 Sep 2015 for Hugintrunk by  doxygen 1.4.7