Fix JPG files do not auto-rotate (closes Issue 125) (on behalf of MaWe)
This commit is contained in:
@@ -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"))
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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 ();
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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");
|
||||
|
@@ -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) {
|
||||
|
@@ -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 ();
|
||||
|
||||
|
Reference in New Issue
Block a user