Skip to content

Commit

Permalink
Respect Exiv2::Value type (e.g. Exiv2::unsignedRational) in readRatio…
Browse files Browse the repository at this point in the history
…nal of QgsExifTools (fixes #57942)
  • Loading branch information
boardend authored and nyalldawson committed Jul 19, 2024
1 parent da74452 commit 6540895
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/core/raster/qgsexiftools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,21 @@
#include <QFileInfo>
#include <QTime>

double readRationale( const Exiv2::Value &value, long n = 0 )
double readRational( const Exiv2::Value &value, long n = 0 )
{
const Exiv2::Rational rational = value.toRational( n );
return static_cast< double >( rational.first ) / rational.second;
const auto numerator = rational.first;
const auto denominator = rational.second;
double res = 0;
if ( value.typeId() == Exiv2::unsignedRational )
{
res = static_cast< double >( static_cast<uint32_t>( numerator ) ) / static_cast<uint32_t>( denominator );
}
else
{
res = static_cast< double >( numerator ) / denominator;
}
return res;
};

double readCoordinate( const Exiv2::Value &value )
Expand All @@ -35,7 +46,7 @@ double readCoordinate( const Exiv2::Value &value )
double div = 1;
for ( int i = 0; i < 3; i++ )
{
res += readRationale( value, i ) / div;
res += readRational( value, i ) / div;
div *= 60;
}
return res;
Expand Down Expand Up @@ -114,7 +125,7 @@ QVariant decodeXmpData( const QString &key, Exiv2::XmpData::const_iterator &it )
{
if ( it->count() == 1 )
{
val = QVariant::fromValue( readRationale( it->value() ) );
val = QVariant::fromValue( readRational( it->value() ) );
}
else
{
Expand Down Expand Up @@ -154,9 +165,9 @@ QVariant decodeExifData( const QString &key, Exiv2::ExifData::const_iterator &it
const QStringList parts = QString::fromStdString( it->toString() ).split( QRegularExpression( QStringLiteral( "\\s+" ) ) );
if ( parts.size() == 3 )
{
const int hour = readRationale( it->value(), 0 );
const int minute = readRationale( it->value(), 1 );
const int second = readRationale( it->value(), 2 );
const int hour = readRational( it->value(), 0 );
const int minute = readRational( it->value(), 1 );
const int second = readRational( it->value(), 2 );
val = QVariant::fromValue( QTime::fromString( QStringLiteral( "%1:%2:%3" )
.arg( QString::number( hour ).rightJustified( 2, '0' ) )
.arg( QString::number( minute ).rightJustified( 2, '0' ) )
Expand Down Expand Up @@ -238,7 +249,7 @@ QVariant decodeExifData( const QString &key, Exiv2::ExifData::const_iterator &it
{
if ( it->count() == 1 )
{
val = QVariant::fromValue( readRationale( it->value() ) );
val = QVariant::fromValue( readRational( it->value() ) );
}
else
{
Expand Down Expand Up @@ -408,7 +419,7 @@ QgsPoint QgsExifTools::getGeoTag( const QString &imagePath, bool &ok )
const Exiv2::ExifData::iterator itElevRefVal = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSAltitudeRef" ) );
if ( itElevVal != exifData.end() )
{
double elev = readRationale( itElevVal->value() );
double elev = readRational( itElevVal->value() );
if ( itElevRefVal != exifData.end() )
{
const QString elevRef = QString::fromStdString( itElevRefVal->value().toString() );
Expand Down

0 comments on commit 6540895

Please sign in to comment.