00001 #include <fstream>
00002 #include <iostream>
00003 #include <sstream>
00004
00005 #include "FCam/F2/EF232LensDatabase.h"
00006 #include "../Debug.h"
00007
00008 #define eprintf(...) \
00009 fprintf(stderr,"EF232[LensDatabase]: ERROR! "); \
00010 fprintf(stderr, __VA_ARGS__);
00011
00012 namespace FCam {
00013
00014 unsigned int EF232LensInfo::minApertureAt(unsigned int focusDistance) const {
00015 if (minApertureList.size() == 0) return 0;
00016 std::map<unsigned int, unsigned int>::const_iterator iter=minApertureList.upper_bound(focusDistance);
00017 if (iter != minApertureList.begin())
00018 iter--;
00019 return iter->second;
00020 }
00021
00022 bool EF232LensInfo::operator<(const EF232LensInfo &rhs) const {
00023 if (focalLengthMin == rhs.focalLengthMin) {
00024 return focalLengthMax < rhs.focalLengthMax;
00025 } else {
00026 return focalLengthMin < rhs.focalLengthMin;
00027 }
00028 }
00029
00030 void EF232LensInfo::print(std::ostream &out) const {
00031 out << "{" << name << "}\n";
00032 out << "focalLengthMin=" << focalLengthMin << std::endl;
00033 out << "focalLengthMax=" << focalLengthMax << std::endl;
00034 out << "focusDistMin=" << focusDistMin << std::endl;
00035 out << "apertureMax=" << apertureMax << std::endl;
00036 out << "focusSpeed=" << focusSpeed << std::endl;
00037 out << "hasImageStabilization=" << hasImageStabilization << std::endl;
00038 out << "hasFullTimeManual=" << hasFullTimeManual << std::endl;
00039 for (minApertureListCIter iter = minApertureList.begin();
00040 iter != minApertureList.end(); iter++) {
00041 out << "aperture["<<iter->first<<"]="<<iter->second<<std::endl;
00042 }
00043 out << std::endl;
00044 }
00045
00046 EF232LensInfo::EF232LensInfo():
00047 name("Unknown"), focalLengthMin(0), focalLengthMax(0),
00048 focusDistMin(0), apertureMax(0), focusSpeed(0),
00049 hasImageStabilization(false),
00050 hasFullTimeManual(false)
00051 {
00052 }
00053
00054 EF232LensDatabase::EF232LensDatabase(const std::string &srcFile) {
00055 if (!db) {
00056 db = new std::set<EF232LensInfo>;
00057 load(srcFile);
00058 }
00059 }
00060
00061 const EF232LensInfo* EF232LensDatabase::find(unsigned int focalLengthMin,
00062 unsigned int focalLengthMax) {
00063 EF232LensInfo key;
00064 key.focalLengthMin = focalLengthMin;
00065 key.focalLengthMax = focalLengthMax;
00066 return find(key);
00067 }
00068
00069 const EF232LensInfo* EF232LensDatabase::find(const EF232LensInfo &key) {
00070 std::set<EF232LensInfo>::iterator iter = db->find(key);
00071 if (iter == db->end()) iter = db->insert(db->begin(), key);
00072 return &*iter;
00073 }
00074
00075 const EF232LensInfo* EF232LensDatabase::update(const EF232LensInfo &lensInfo) {
00076 std::set<EF232LensInfo>::iterator iter = db->find(lensInfo);
00077 if (iter != db->end()) db->erase(iter++);
00078 return &*(db->insert(iter, lensInfo));
00079 }
00080
00081 void EF232LensDatabase::load(const std::string &srcFile) {
00082 std::ifstream dbFile(srcFile.c_str());
00083
00084 if (!dbFile.is_open()) {
00085 dprintf(1, "Unable to open database file %s\n", srcFile.c_str());
00086 return;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 std::string line;
00099 std::size_t pos1,pos2;
00100 int lineNum = 0;
00101 EF232LensInfo *newLens = NULL;
00102 while(!dbFile.eof()) {
00103 std::getline(dbFile, line);
00104 lineNum++;
00105 line = line.substr(0, line.find_first_of("#"));
00106
00107 if ( (pos1 = line.find_first_of('{') != line.npos) ) {
00108 if (newLens != NULL) {
00109 db->insert(*newLens);
00110 delete newLens;
00111 }
00112
00113 pos2=line.find_first_of('}');
00114 if (pos2 == line.npos) {
00115 eprintf("Malformed database entry on line %d: %s\n", lineNum, line.c_str());
00116 return;
00117 }
00118 newLens = new EF232LensInfo;
00119 newLens->name = line.substr(pos1, pos2-pos1);
00120 dprintf(1, "Reading in lens information for lens '%s'\n", newLens->name.c_str());
00121 }
00122
00123 if ( (pos1 = line.find_first_of('=')) != line.npos ) {
00124 std::string attribute = line.substr(0, pos1);
00125 std::stringstream value(line.substr(pos1+1));
00126 dprintf(1, " Attribute: %s, value: %s\n", attribute.c_str(), value.str().c_str());
00127 value >> std::ws;
00128 if (attribute.find("focalLengthMin") != attribute.npos) {
00129 value >> newLens->focalLengthMin;
00130 } else if (attribute.find("focalLengthMax") != attribute.npos) {
00131 value >> newLens->focalLengthMax;
00132 } else if (attribute.find("focusDistMin") != attribute.npos) {
00133 value >> newLens->focusDistMin;
00134 } else if (attribute.find("apertureMax") != attribute.npos) {
00135 value >> newLens->apertureMax;
00136 } else if (attribute.find("focusSpeed") != attribute.npos) {
00137 value >> newLens->focusSpeed;
00138 } else if (attribute.find("hasImageStabilization") != attribute.npos) {
00139 value >> newLens->hasImageStabilization;
00140 } else if (attribute.find("hasFullTimeManual") != attribute.npos ){
00141 value >> newLens->hasFullTimeManual;
00142 } else if (attribute.find("aperture") != attribute.npos ){
00143 pos1 = attribute.find_first_of('[');
00144 pos2 = attribute.find_first_of(']',pos1);
00145 if (pos1 == attribute.npos || pos2 == attribute.npos) {
00146 eprintf("Malformed database entry on line %d: %s\n", lineNum, line.c_str());
00147 return;
00148 }
00149 std::stringstream index(attribute.substr(pos1+1, pos2-pos1-1));
00150 index >> std::ws;
00151 EF232LensInfo::apertureChange newApertureChange;
00152 index >> newApertureChange.first;
00153 value >> newApertureChange.second;
00154 newLens->minApertureList.insert(newApertureChange);
00155 } else {
00156 eprintf("Ignoring unknown database field %s on line %d: %s\n", attribute.c_str(), lineNum, line.c_str());
00157 }
00158 }
00159 }
00160 if (newLens != NULL) {
00161 db->insert(*newLens);
00162 delete newLens;
00163 }
00164 }
00165
00166 void EF232LensDatabase::save(const std::string &dstFile) const {
00167 std::ofstream dbFile(dstFile.c_str());
00168 if (!dbFile.is_open()) {
00169 eprintf("Unable to open database file %s for writing!\n", dstFile.c_str());
00170 return;
00171 }
00172
00173 dbFile << "########################\n";
00174 dbFile << "# EF-232 Lens Database file for Canon EOS lens parameters\n";
00175 dbFile << "# Auto-generated by EF232LensDatabase.cpp\n";
00176 dbFile << "# Units in mm, f/stops, or 0=false, 1=true\n";
00177 dbFile << "\n\n";
00178
00179 for (std::set<EF232LensInfo>::iterator dbIter = db->begin();
00180 dbIter != db->end();
00181 dbIter++) {
00182 dbIter->print(dbFile);
00183 }
00184
00185 dbFile <<"\n\n";
00186 dbFile <<"# End autogenerated lens database file\n";
00187 }
00188
00189 std::set<EF232LensInfo> *EF232LensDatabase::db = NULL;
00190
00191 }