Fix JPG files do not auto-rotate (closes Issue 125) (on behalf of MaWe)

This commit is contained in:
Philip Rinn
2011-08-31 17:47:35 +02:00
parent ec918d2f56
commit f89fcd56ba
8 changed files with 84 additions and 40 deletions

View File

@@ -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"))

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 ();

View File

@@ -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);

View File

@@ -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");

View File

@@ -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) {

View File

@@ -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 ();