diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 095924a8c..101acbf3f 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -89,6 +89,7 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { lens = "Unknown"; make = "Unknown"; model = "Unknown"; + orientation = "Unknown"; focal_len = 0; memset (&time, 0, sizeof(time)); } @@ -104,6 +105,7 @@ void ImageData::extractInfo () { make = ""; model = ""; serial = ""; + orientation = ""; shutter = 0; aperture = 0; focal_len = 0; @@ -144,6 +146,9 @@ void ImageData::extractInfo () { if( model.find( "Digital Camera ") != std::string::npos ) model.erase(0,15); } + if (root->getTag ("Orientation")){ + orientation = root->getTag ("Orientation")->valueToString (); + } rtexif::TagDirectory* exif = NULL; if (root->getTag ("Exif")) diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 967987a76..8d568cbb9 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -43,6 +43,7 @@ class ImageData : public ImageMetaData { double focal_len; double shutter; std::string make, model, serial; + std::string orientation; std::string lens; void extractInfo (); @@ -68,6 +69,7 @@ class ImageData : public ImageMetaData { std::string getModel () const { return model; } std::string getLens () const { return lens; } std::string getSerialNumber () const { return serial;} + std::string getOrientation () const { return orientation; } }; }; #endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 4555cd8bb..6b34ebcea 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -80,6 +80,8 @@ namespace rtengine { /** @return the lens on the camera */ virtual std::string getLens () const =0; + /** @return the orientation of the image */ + virtual std::string getOrientation () const =0; /** Functions to convert between floating point and string representation of shutter and aperture */ static std::string apertureToString (double aperture); /** Functions to convert between floating point and string representation of shutter and aperture */ diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 08fa784ba..c32fdb509 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -42,7 +42,7 @@ namespace rtengine { -Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh) { +Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, int deg) { Image16* img = new Image16 (); int err = img->load (fname); @@ -50,6 +50,11 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, delete img; return NULL; } + if (deg) { + Image16* rot = img->rotate(deg); + delete img; + img = rot; + } Thumbnail* tpp = new Thumbnail (); diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index 935095e9d..732fbc291 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -77,7 +77,7 @@ namespace rtengine { static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate); static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate); - static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh); + static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, int deg=0); void getCamWB (double& temp, double& green); void getAutoWB (double& temp, double& green); diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 7ac76db5f..b76762152 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -90,6 +90,23 @@ int StdImageSource::load (Glib::ustring fname, bool batch) { embProfile = img->getEmbeddedProfile (); idata = new ImageData (fname); + if (idata->hasExif()) { + int deg = 0; + if (idata->getOrientation()=="Rotate 90 CW") { + deg = 90; + } + else if (idata->getOrientation()=="Rotate 180") { + deg = 180; + } + else if (idata->getOrientation()=="Rotate 270 CW") { + deg = 270; + } + if (deg) { + Image16* rot = img->rotate(deg); + delete img; + img = rot; + } + } if (plistener) { plistener->setProgressStr ("PROGRESSBAR_READY"); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 20ea707dc..8896d5cbb 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -95,23 +95,23 @@ void Thumbnail::_generateThumbnailImage () { cfs.exifValid = false; cfs.timeValid = false; - if (ext.lowercase()=="jpg" || ext.lowercase()=="png" || ext.lowercase()=="tif" || ext.lowercase()=="tiff") { - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1); - if (tpp) { - if (ext.lowercase()=="jpg") { + if (ext.lowercase()=="jpg") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, infoFromImage (fname)); + if (tpp) cfs.format = FT_Jpeg; - infoFromImage (fname); - } - else if (ext.lowercase()=="png") - cfs.format = FT_Png; - else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") { - cfs.format = FT_Tiff; - infoFromImage (fname); - } - } } - else { - // RAW works like this: + else if (ext.lowercase()=="png") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1); + if (tpp) + cfs.format = FT_Png; + } + else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, infoFromImage (fname)); + if (tpp) + cfs.format = FT_Tiff; + } + else { + // RAW works like this: // 1. if we are here it's because we aren't in the cache so load the JPG // image out of the RAW. Mark as "quick". // 2. if we don't find that then just grab the real image. @@ -398,29 +398,29 @@ void Thumbnail::getThumbnailSize (int &w, int &h) { } } -void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h) { +void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h) { // TODO: Check for Linux #ifdef WIN32 Glib::Mutex::Lock lock(mutex); - #endif - - // WARNING: When downscaled, the ratio have loosed a lot of precision, so we can't get back the exact initial dimensions - double fw = lastW*lastScale; - double fh = lastH*lastScale; - - if (pparams.coarse.rotate==90 || pparams.coarse.rotate==270) { - fh = lastW*lastScale; - fw = lastH*lastScale; - } - if (!pparams.resize.enabled) { - w = fw; - h = fh; - } - else { - w = (int)(fw+0.5); - h = (int)(fh+0.5); - } -} + #endif + + // WARNING: When downscaled, the ratio have loosed a lot of precision, so we can't get back the exact initial dimensions + double fw = lastW*lastScale; + double fh = lastH*lastScale; + + if (pparams.coarse.rotate==90 || pparams.coarse.rotate==270) { + fh = lastW*lastScale; + fw = lastH*lastScale; + } + if (!pparams.resize.enabled) { + w = fw; + h = fh; + } + else { + w = (int)(fw+0.5); + h = (int)(fh+0.5); + } +} rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) { @@ -534,11 +534,13 @@ ThFileType Thumbnail::getType () { return (ThFileType) cfs.format; } -void Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml) { +int Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml) { rtengine::ImageMetaData* idata = rtengine::ImageMetaData::fromFile (fname, rml); if (!idata) - return; + return 0; + + int deg = 0; cfs.timeValid = false; cfs.exifValid = false; if (idata->hasExif()) { @@ -556,6 +558,16 @@ void Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaData cfs.exifValid = true; cfs.lens = idata->getLens(); cfs.camera = idata->getCamera(); + + if (idata->getOrientation()=="Rotate 90 CW") { + deg = 90; + } + else if (idata->getOrientation()=="Rotate 180") { + deg = 180; + } + else if (idata->getOrientation()=="Rotate 270 CW") { + deg = 270; + } } else { cfs.lens = "Unknown"; @@ -568,6 +580,7 @@ void Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaData else {cfs.filetype="";} delete idata; + return deg; } void Thumbnail::_loadThumbnail(bool firstTrial) { diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 6d7992296..088d017c7 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -69,7 +69,7 @@ class Thumbnail { void _loadThumbnail (bool firstTrial=true); void _saveThumbnail (); void _generateThumbnailImage (); - void infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml=NULL); + int infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml=NULL); void loadThumbnail (bool firstTrial=true); void generateExifDateTimeStrings ();