31 #include <exiv2/exiv2.hpp>
38 bool _getExiv2Value(Exiv2::ExifData& exifData, std::string keyName,
long & value)
40 Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(keyName));
41 if (itr != exifData.end() && itr->count())
43 #if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,28,0)
44 value = itr->toInt64();
46 value = itr->toLong();
56 bool _getExiv2Value(Exiv2::ExifData& exifData, std::string keyName,
float & value)
58 Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(keyName));
59 if (itr != exifData.end() && itr->count())
61 value = itr->toFloat();
70 bool _getExiv2Value(Exiv2::ExifData& exifData, std::string keyName, std::string & value)
72 Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(keyName));
73 if (itr != exifData.end() && itr->count())
75 value = itr->toString();
84 bool _getExiv2Value(Exiv2::ExifData& exifData, std::string keyName, std::vector<float> & values)
87 Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(keyName));
88 if (itr != exifData.end() && itr->count())
90 for(
long i=0; i<itr->count(); i++)
92 values.push_back(itr->toFloat(i));
102 bool _getExiv2Value(Exiv2::ExifData& exifData, uint16_t tagID, std::string groupName, std::string & value)
104 Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(tagID, groupName));
105 if (itr != exifData.end() && itr->count())
107 value = itr->toString();
116 bool _getExiv2Value(Exiv2::ExifData& exifData, uint16_t tagID, std::string groupName,
double & value)
118 Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(tagID, groupName));
119 if (itr != exifData.end() && itr->count())
121 value = itr->toFloat();
132 if(it!=exifData.end() && it->count())
134 return it->toFloat();
151 if(it!=exifData.end() && it->count())
155 return std::string(
"");
165 return std::string(
"");
170 if(it!=exifData.end() && it->count())
172 #if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,28,0)
173 return it->toInt64();
193 Exiv2::ExifData::iterator lat = exifData.findKey(Exiv2::ExifKey(
"Exif.GPSInfo.GPSLatitude"));
194 Exiv2::ExifData::iterator latRef = exifData.findKey(Exiv2::ExifKey(
"Exif.GPSInfo.GPSLatitudeRef"));
196 if (lat != exifData.end() && latRef != exifData.end())
199 if (lat->value().typeId() == Exiv2::unsignedRational)
203 for (
int i = 0; i < lat->value().count(); i++)
205 value += lat->value().toFloat(i) / denom;
208 if (latRef->toString() ==
"S")
221 Exiv2::ExifData::iterator longitudeTag = exifData.findKey(Exiv2::ExifKey(
"Exif.GPSInfo.GPSLongitude"));
222 Exiv2::ExifData::iterator longitudeRef = exifData.findKey(Exiv2::ExifKey(
"Exif.GPSInfo.GPSLongitudeRef"));
224 if (longitudeTag != exifData.end() && longitudeRef != exifData.end())
227 if (longitudeTag->value().typeId() == Exiv2::unsignedRational)
231 for (
int i = 0; i < longitudeTag->value().count(); i++)
233 value += longitudeTag->value().toFloat(i) / denom;
236 if (longitudeRef->toString() ==
"W")
250 std::cout << itr->value() <<
" (" << itr->typeName() <<
", size: " << itr->count() <<
")" << std::endl;
254 for(
long i=0; i<itr->count(); i++)
256 std::cout << itr->toFloat(i) <<
",";
258 std::cout <<
"]" << std::endl;
267 float val1=0, val2=0, val3=0;
268 std::vector<float> values;
273 if(val1!=0 && val2!=0 && val3!=0)
275 redBalance=val1 / val2;;
276 blueBalance=val3 / val2;
288 if(val1!=0 && val2!=0)
290 redBalance=val1 / 8192.0;
291 blueBalance=val2 / 8192.0;
299 #if defined EXIV2_VERSION && EXIV2_VERSION >= EXIV2_MAKE_VERSION(0,23,0)
300 if (
_getExiv2Value(exifData,
"Exif.PentaxDng.RedBalance", val1) &&
303 if(val1!=0 && val2!=0)
305 redBalance=val1 / 256.0;
306 blueBalance=val2 / 256.0;
319 if(val1!=0 && val2!=0)
321 redBalance=val1 / 256.0;
322 blueBalance=val2 / 256.0;
330 if(
_getExiv2Value(exifData,
"Exif.OlympusIp.WB_RBLevels", values))
334 if(values[0]!=0 && values[1]!=0)
336 redBalance=values[0]/256.0;
337 blueBalance=values[1]/256.0;
355 if(values[0]!=0 && values[1]!=0)
357 redBalance=values[0];
358 blueBalance=values[1];
371 if(
_getExiv2Value(exifData,
"Exif.NikonCb1.WB_RBGGLevels", values))
375 if(values[0]!=0 && values[1]!=0 && values[2]!=0 && values[3]!=0)
377 redBalance=values[0] / values[2];
378 blueBalance=values[1] / values[2];
391 if(
_getExiv2Value(exifData,
"Exif.NikonCb2.WB_RGGBLevels", values))
395 if(values[0]!=0 && values[1]!=0 && values[2]!=0 && values[3]!=0)
397 redBalance=values[0] / values[1];
398 blueBalance=values[3] / values[1];
411 if(
_getExiv2Value(exifData,
"Exif.NikonCb2a.WB_RGGBLevels", values))
415 if(values[0]!=0 && values[1]!=0 && values[2]!=0 && values[3]!=0)
417 redBalance=values[0] / values[1];
418 blueBalance=values[3] / values[1];
431 if(
_getExiv2Value(exifData,
"Exif.NikonCb2b.WB_RGGBLevels", values))
435 if(values[0]!=0 && values[1]!=0 && values[2]!=0 && values[3]!=0)
437 redBalance=values[0] / values[1];
438 blueBalance=values[3] / values[1];
451 if(
_getExiv2Value(exifData,
"Exif.NikonCb3.WB_RGBGLevels", values))
455 if(values[0]!=0 && values[1]!=0 && values[2]!=0 && values[3]!=0)
457 redBalance=values[0] / values[1];
458 blueBalance=values[2] / values[3];
475 const double getCropFactor(Exiv2::ExifData &exifData,
long width,
long height)
486 double sensorPixelWidth = 0;
487 double sensorPixelHeight = 0;
488 if (eWidth > 0 && eLength > 0)
490 sensorPixelHeight = (double)eLength;
491 sensorPixelWidth = (double)eWidth;
496 sensorPixelWidth = width;
497 sensorPixelHeight = height;
501 if (sensorPixelWidth < sensorPixelHeight )
503 double t = sensorPixelWidth;
504 sensorPixelWidth = sensorPixelHeight;
505 sensorPixelHeight = t;
508 DEBUG_DEBUG(
"sensorPixelWidth: " << sensorPixelWidth);
509 DEBUG_DEBUG(
"sensorPixelHeight: " << sensorPixelHeight);
514 long exifResolutionUnits = 0;
515 _getExiv2Value(exifData,
"Exif.Photo.FocalPlaneResolutionUnit",exifResolutionUnits);
517 float resolutionUnits= 0;
518 switch (exifResolutionUnits)
520 case 3: resolutionUnits = 10.0f;
break;
521 case 4: resolutionUnits = 1.0f;
break;
522 case 5: resolutionUnits = .001f;
break;
523 default: resolutionUnits = 25.4f;
break;
526 DEBUG_DEBUG(
"Resolution Units: " << resolutionUnits);
530 float fplaneXresolution = 0;
531 _getExiv2Value(exifData,
"Exif.Photo.FocalPlaneXResolution",fplaneXresolution);
533 float fplaneYresolution = 0;
534 _getExiv2Value(exifData,
"Exif.Photo.FocalPlaneYResolution",fplaneYresolution);
537 if (fplaneXresolution != 0)
539 CCDWidth = (float)(sensorPixelWidth / ( fplaneXresolution / resolutionUnits));
543 if (fplaneYresolution != 0)
545 CCDHeight = (float)(sensorPixelHeight / ( fplaneYresolution / resolutionUnits));
553 if (CCDHeight > 0 && CCDWidth > 0)
556 sensorSize.
x = CCDWidth;
557 sensorSize.
y = CCDHeight;
558 std::string exifModel;
561 if (exifModel ==
"Canon EOS 20D")
569 double rsensor = (double)sensorSize.
x / sensorSize.
y;
570 double rimg = (
double) width / height;
571 if ( (rsensor > 1 && rimg < 1) || (rsensor < 1 && rimg > 1) )
577 sensorSize.
y = sensorSize.
x;
584 cropFactor = sqrt(36.0*36.0+24.0*24.0) /
585 sqrt(sensorSize.
x*sensorSize.
x + sensorSize.
y*sensorSize.
y);
587 if (cropFactor < 0.1 || cropFactor > 100)
603 _getExiv2Value(exifData,
"Exif.Olympus.FocalPlaneDiagonal",olyFPD);
609 cropFactor = sqrt(36.0*36.0+24.0*24.0) / olyFPD;
615 _getExiv2Value(exifData,
"Exif.OlympusEq.FocalPlaneDiagonal",olyFPD);
618 cropFactor = sqrt(36.0*36.0+24.0*24.0) / olyFPD;
627 std::string lensName;
630 #if defined EXIV2_VERSION && EXIV2_VERSION >= EXIV2_MAKE_VERSION(0,22,0)
637 if(lensName.length()>0)
645 Exiv2::ExifData::const_iterator itr2 = Exiv2::lensName(exifData);
646 if (itr2!=exifData.end() && itr2->count())
650 lensName=itr2->print(&exifData);
652 if(lensName.length()>0)
656 if(lensName.compare(0, 1,
"(")!=0 && lensName.compare(0, 7,
"Unknown")!=0)
663 return std::string(
"");
const std::string getLensName(Exiv2::ExifData &exifData)
std::string StrTrim(const std::string &str)
remove trailing and leading white spaces and tabs
bool _getExiv2Value(Exiv2::ExifData &exifData, std::string keyName, long &value)
misc math function & classes used by other parts of the program
const double getExiv2ValueDouble(Exiv2::ExifData &exifData, Exiv2::ExifData::const_iterator it)
const long getExiv2ValueLong(Exiv2::ExifData &exifData, Exiv2::ExifData::const_iterator it)
const std::string getExiv2ValueString(Exiv2::ExifData &exifData, Exiv2::ExifData::const_iterator it)
bool getExiv2GPSLongitude(Exiv2::ExifData &exifData, double &longitude)
const double getCropFactor(Exiv2::ExifData &exifData, long width, long height)
bool getExiv2GPSLatitude(Exiv2::ExifData &exifData, double &latitude)
helper functions to work with Exif data via the exiv2 library
void PrintTag(Exiv2::ExifData::iterator itr)
bool readRedBlueBalance(Exiv2::ExifData &exifData, double &redBalance, double &blueBalance)