Merge pull request #5325 from erjiang/embedded-ratings

Use ratings from image metadata
This commit is contained in:
Beep6581
2019-07-17 13:19:16 +02:00
committed by Morgan Hardwood
8 changed files with 119 additions and 29 deletions

View File

@@ -69,36 +69,40 @@ FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname, std::uniqu
return new FramesData (fname, std::move(rml), firstFrameOnly); return new FramesData (fname, std::move(rml), firstFrameOnly);
} }
FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) :
: frameRootDir(frameRootDir_), iptc(nullptr), time(), timeStamp(), iso_speed(0), aperture(0.), focal_len(0.), focal_len35mm(0.), focus_dist(0.f), frameRootDir(frameRootDir_),
shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), lens("Unknown"), iptc(nullptr),
sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false) time{},
timeStamp{},
iso_speed(0),
aperture(0.),
focal_len(0.),
focal_len35mm(0.),
focus_dist(0.f),
shutter(0.),
expcomp(0.),
make("Unknown"),
model("Unknown"),
orientation("Unknown"),
rating(0),
lens("Unknown"),
sampleFormat(IIOSF_UNKNOWN),
isPixelShift(false),
isHDR(false)
{ {
memset (&time, 0, sizeof(time));
if (!frameRootDir) { if (!frameRootDir) {
return; return;
} }
rtexif::Tag* tag;
rtexif::TagDirectory* newFrameRootDir = frameRootDir;
memset(&time, 0, sizeof(time));
timeStamp = 0;
iso_speed = 0;
aperture = 0.0;
focal_len = 0.0;
focal_len35mm = 0.0;
focus_dist = 0.0f;
shutter = 0.0;
expcomp = 0.0;
make.clear(); make.clear();
model.clear(); model.clear();
serial.clear(); serial.clear();
orientation.clear(); orientation.clear();
lens.clear(); lens.clear();
tag = newFrameRootDir->findTag("Make"); rtexif::TagDirectory* newFrameRootDir = frameRootDir;
rtexif::Tag* tag = newFrameRootDir->findTag("Make");
if (!tag) { if (!tag) {
newFrameRootDir = rootDir; newFrameRootDir = rootDir;
tag = newFrameRootDir->findTag("Make"); tag = newFrameRootDir->findTag("Make");
@@ -187,6 +191,23 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
orientation = tag->valueToString (); orientation = tag->valueToString ();
} }
// Look for Rating metadata in the following order:
// 1. EXIF
// 2. XMP
// 3. pp3 sidecar file
tag = newFrameRootDir->findTagUpward("Rating");
if (tag && tag->toInt() != 0) {
rating = tag->toInt();
}
char sXMPRating[64];
if (newFrameRootDir->getXMPTagValue("xmp:Rating", sXMPRating)) {
// Guard against out-of-range values (<0, >5)
rating = rtengine::max(0, rtengine::min(5, atoi(sXMPRating)));
// Currently, Rating=-1 is not supported. A value of -1 should mean
// "Rejected" according to the specification. Maybe in the future, Rating=-1
// sets InTrash=true?
}
tag = newFrameRootDir->findTagUpward("MakerNote"); tag = newFrameRootDir->findTagUpward("MakerNote");
rtexif::TagDirectory* mnote = nullptr; rtexif::TagDirectory* mnote = nullptr;
if (tag) { if (tag) {
@@ -876,6 +897,11 @@ std::string FrameData::getOrientation () const
return orientation; return orientation;
} }
int FrameData::getRating () const
{
return rating;
}
void FramesData::setDCRawFrameCount (unsigned int frameCount) void FramesData::setDCRawFrameCount (unsigned int frameCount)
@@ -1169,10 +1195,20 @@ std::string FramesData::getOrientation(unsigned int frame) const
); );
} }
int FramesData::getRating(unsigned int frame) const
{
return getFromFrame<int>(
frames,
frame,
[](const FrameData& frame_data)
{
return frame_data.getRating();
}
);
}
//------inherited functions--------------// //------inherited functions--------------//
std::string FramesMetaData::apertureToString (double aperture) std::string FramesMetaData::apertureToString (double aperture)
{ {

View File

@@ -48,6 +48,7 @@ protected:
double expcomp; double expcomp;
std::string make, model, serial; std::string make, model, serial;
std::string orientation; std::string orientation;
int rating;
std::string lens; std::string lens;
IIOSampleFormat sampleFormat; IIOSampleFormat sampleFormat;
@@ -84,6 +85,7 @@ public:
std::string getLens () const; std::string getLens () const;
std::string getSerialNumber () const; std::string getSerialNumber () const;
std::string getOrientation () const; std::string getOrientation () const;
int getRating () const;
}; };
class FramesData : public FramesMetaData { class FramesData : public FramesMetaData {
@@ -126,6 +128,7 @@ public:
std::string getLens (unsigned int frame = 0) const override; std::string getLens (unsigned int frame = 0) const override;
std::string getSerialNumber (unsigned int frame = 0) const; std::string getSerialNumber (unsigned int frame = 0) const;
std::string getOrientation (unsigned int frame = 0) const override; std::string getOrientation (unsigned int frame = 0) const override;
int getRating (unsigned int frame = 0) const override;
}; };

View File

@@ -2853,7 +2853,10 @@ void ProcParams::setDefaults()
exif.clear(); exif.clear();
iptc.clear(); iptc.clear();
rank = 0; // -1 means that there's no pp3 data with rank yet. In this case, the
// embedded Rating metadata should take precedence. -1 should never be
// written to pp3 on disk.
rank = -1;
colorlabel = 0; colorlabel = 0;
inTrash = false; inTrash = false;

View File

@@ -139,6 +139,8 @@ public:
virtual std::string getLens (unsigned int frame = 0) const = 0; virtual std::string getLens (unsigned int frame = 0) const = 0;
/** @return the orientation of the image */ /** @return the orientation of the image */
virtual std::string getOrientation (unsigned int frame = 0) const = 0; virtual std::string getOrientation (unsigned int frame = 0) const = 0;
/** @return the rating of the image */
virtual int getRating (unsigned int frame = 0) const = 0;
/** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */
virtual bool getPixelShift () const = 0; virtual bool getPixelShift () const = 0;

View File

@@ -3037,6 +3037,12 @@ void ExifManager::parse (bool isRaw, bool skipIgnored)
} }
} }
if (!root->getTag ("Rating")) {
Tag *t = new Tag (root, root->getAttrib("Rating"));
t->initInt (0, LONG);
root->addTag (t);
}
// --- detecting image root IFD based on SubFileType, or if not provided, on PhotometricInterpretation // --- detecting image root IFD based on SubFileType, or if not provided, on PhotometricInterpretation
bool frameRootDetected = false; bool frameRootDetected = false;

View File

@@ -24,12 +24,37 @@
#include "../rtengine/procparams.h" #include "../rtengine/procparams.h"
CacheImageData::CacheImageData () CacheImageData::CacheImageData() :
: md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), supported(false),
timeValid(false), year(0), month(0), day(0), hour(0), min(0), sec(0), exifValid(false), frameCount(1), format(FT_Invalid),
fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), isHDR (false), rankOld(-1),
isPixelShift (false), sensortype(rtengine::ST_NONE), sampleFormat(rtengine::IIOSF_UNKNOWN), inTrashOld(false),
redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), rotate(0), thumbImgType(0) recentlySaved(false),
timeValid(false),
year(0),
month(0),
day(0),
hour(0),
min(0),
sec(0),
exifValid(false),
frameCount(1),
fnumber(0.0),
shutter(0.0),
focalLen(0.0),
focalLen35mm(0.0),
focusDist(0.f),
iso(0),
rating(0),
isHDR (false),
isPixelShift (false),
sensortype(rtengine::ST_NONE),
sampleFormat(rtengine::IIOSF_UNKNOWN),
redAWBMul(-1.0),
greenAWBMul(-1.0),
blueAWBMul(-1.0),
rotate(0),
thumbImgType(0)
{ {
} }
@@ -66,6 +91,10 @@ int CacheImageData::load (const Glib::ustring& fname)
rankOld = keyFile.get_integer ("General", "Rank"); rankOld = keyFile.get_integer ("General", "Rank");
} }
if (keyFile.has_key ("General", "Rating")) {
rating = keyFile.get_integer ("General", "Rating");
}
if (keyFile.has_key ("General", "InTrash")) { if (keyFile.has_key ("General", "InTrash")) {
inTrashOld = keyFile.get_boolean ("General", "InTrash"); inTrashOld = keyFile.get_boolean ("General", "InTrash");
} }
@@ -227,6 +256,7 @@ int CacheImageData::save (const Glib::ustring& fname)
keyFile.set_boolean ("General", "Supported", supported); keyFile.set_boolean ("General", "Supported", supported);
keyFile.set_integer ("General", "Format", format); keyFile.set_integer ("General", "Format", format);
keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); keyFile.set_boolean ("General", "RecentlySaved", recentlySaved);
keyFile.set_integer ("General", "Rating", rating);
// remove the old implementation of Rank and InTrash from cache // remove the old implementation of Rank and InTrash from cache
if (keyFile.has_key ("General", "Rank")) { if (keyFile.has_key ("General", "Rank")) {

View File

@@ -54,6 +54,7 @@ public:
double focalLen, focalLen35mm; double focalLen, focalLen35mm;
float focusDist; float focusDist;
unsigned iso; unsigned iso;
int rating;
bool isHDR; bool isHDR;
bool isPixelShift; bool isPixelShift;
int sensortype; int sensortype;
@@ -108,6 +109,7 @@ public:
std::string getModel (unsigned int frame = 0) const override { return camModel; } std::string getModel (unsigned int frame = 0) const override { return camModel; }
std::string getLens (unsigned int frame = 0) const override { return lens; } std::string getLens (unsigned int frame = 0) const override { return lens; }
std::string getOrientation (unsigned int frame = 0) const override { return ""; } // TODO std::string getOrientation (unsigned int frame = 0) const override { return ""; } // TODO
int getRating (unsigned int frame = 0) const override { return rating; } // FIXME-piotr : missing rating
bool getPixelShift () const override { return isPixelShift; } bool getPixelShift () const override { return isPixelShift; }
bool getHDR (unsigned int frame = 0) const override { return isHDR; } bool getHDR (unsigned int frame = 0) const override { return isHDR; }
std::string getImageType (unsigned int frame) const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } std::string getImageType (unsigned int frame) const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; }

View File

@@ -813,6 +813,7 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptr<rtengi
cfs.lens = idata->getLens(); cfs.lens = idata->getLens();
cfs.camMake = idata->getMake(); cfs.camMake = idata->getMake();
cfs.camModel = idata->getModel(); cfs.camModel = idata->getModel();
cfs.rating = idata->getRating();
if (idata->getOrientation() == "Rotate 90 CW") { if (idata->getOrientation() == "Rotate 90 CW") {
deg = 90; deg = 90;
@@ -1005,15 +1006,22 @@ void Thumbnail::setFileName (const Glib::ustring &fn)
int Thumbnail::getRank () const int Thumbnail::getRank () const
{ {
return pparams->rank; // prefer the user-set rank over the embedded Rating
// pparams->rank == -1 means that there is no saved rank yet, so we should
// next look for the embedded Rating metadata.
if (pparams->rank != -1) {
return pparams->rank;
} else {
return cfs.rating;
}
} }
void Thumbnail::setRank (int rank) void Thumbnail::setRank (int rank)
{ {
if (pparams->rank != rank) { if (pparams->rank != rank) {
pparams->rank = rank; pparams->rank = rank;
pparamsValid = true;
} }
pparamsValid = true;
} }
int Thumbnail::getColorLabel () const int Thumbnail::getColorLabel () const