diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 585009c6a..2a8419494 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -172,10 +172,22 @@ void ImageData::extractInfo () { focal_len = exif->getTag ("FocalLength")->toDouble (); if (exif->getTag ("FocalLengthIn35mmFilm")) focal_len35mm = exif->getTag ("FocalLengthIn35mmFilm")->toDouble (); - rtexif::Tag* pDst=exif->getTag("SubjectDistance"); // EXIF, set by Adobe. MakerNote ones are scattered and partly encrypted + + // Focus distance from EXIF or XMP. MakerNote ones are scattered and partly encrypted + int num=-3, denom=-3; + + // First try, offical EXIF. Set by Adobe on some DNGs + rtexif::Tag* pDst=exif->getTag("SubjectDistance"); if (pDst) { int num, denom; pDst->toRational(num,denom); + } else { + // Second try, XMP data + char sXMPVal[64]; + if (root->getXMPTagValue("aux:ApproximateFocusDistance",sXMPVal)) { sscanf(sXMPVal,"%d/%d",&num,&denom); } + } + + if (num!=-3) { if ((denom==1 && num>=10000) || num<0 || denom<0) focus_dist=10000; // infinity else if (denom>0) { diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index da4fdc8b7..9bab4de2b 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -213,6 +213,51 @@ Tag* TagDirectory::findTag (const char* name) const { return NULL; } +// Searches a simple value, as either attribute or element +// only for simple values, not for entries with special chars or free text +bool TagDirectory::getXMPTagValue(const char* name, char* value) const { + *value=0; + + if (!getTag("ApplicationNotes")) return false; + char *sXMP = (char*)getTag("ApplicationNotes")->getValue(); + + // Check for full word + char *pos=sXMP; + + bool found=false; + do { + pos=strstr(pos,name); + if (pos) { + char nextChar=*(pos+strlen(name)); + if (nextChar==' ' || nextChar=='>' || nextChar=='=') + found=true; + else + pos+=strlen(name); + } + } while (pos && !found); + if (!found) return false; + + char *posTag =strchr(pos,'>'); + char *posAttr=strchr(pos,'"'); + + if (!posTag && !posAttr) return false; + + if (posTag && (!posAttr || posTaggetID()==ID) tags[i]->setKeep(true); diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 020062c5d..185aee9fc 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -83,6 +83,7 @@ class TagDirectory { virtual Tag* getTag (const char* name) const; virtual Tag* getTag (int ID) const; virtual Tag* findTag (const char* name) const; + bool getXMPTagValue(const char* name, char* value) const; void keepTag (int ID); virtual void addTag (Tag* a);