From 2baca3346ee704acaa7d49132d37d8f1d7faeede Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 24 Apr 2023 13:25:19 +0200 Subject: [PATCH] Simplify the ExposureTime fraction in ExifUtil::getFormattedExifData() see https://www.woltlab.com/community/thread/298320-fehlerhafte-exif-daten/ --- .../install/files/lib/util/ExifUtil.class.php | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/wcfsetup/install/files/lib/util/ExifUtil.class.php b/wcfsetup/install/files/lib/util/ExifUtil.class.php index 81a6a92a80..8878f5dee3 100644 --- a/wcfsetup/install/files/lib/util/ExifUtil.class.php +++ b/wcfsetup/install/files/lib/util/ExifUtil.class.php @@ -211,7 +211,7 @@ final class ExifUtil // unit is second (unsigned rational) if (isset($rawExifData['ExposureTime']) && \is_string($rawExifData['ExposureTime'])) { - $exifData['ExposureTime'] = $rawExifData['ExposureTime']; + $exifData['ExposureTime'] = self::simplifyRational($rawExifData['ExposureTime']); } // actual F-number(F-stop) of lens when the image was taken (unsigned rational) if (isset($rawExifData['FNumber']) && \is_string($rawExifData['FNumber'])) { @@ -254,11 +254,8 @@ final class ExifUtil /** * Converts the format of exif geo tagging coordinates. - * - * @param string $coordinate - * @return double */ - private static function convertCoordinateToDecimal($coordinate) + private static function convertCoordinateToDecimal(string $coordinate): float { $result = 0.0; $coordinateData = \explode('/', $coordinate); @@ -275,11 +272,8 @@ final class ExifUtil /** * Converts a exif rational value to a float. - * - * @param string $rational - * @return float */ - private static function convertExifRational($rational) + private static function convertExifRational(string $rational): float { $data = \explode('/', $rational); if (\count($data) == 1) { @@ -294,4 +288,32 @@ final class ExifUtil return \floatval($data[0]) / $data[1]; } + + private static function simplifyRational(string $rational): string + { + $data = \explode('/', $rational); + if (\count($data) == 1) { + return $data; + } + + $numerator = $data[0]; + $denonimator = $data[1]; + $gcd = self::gcd($numerator, $denonimator); + + return \sprintf('%d/%d', $numerator / $gcd, $denonimator / $gcd); + } + + /** + * Implements the Euclidian Algorithm to calculate the GCD. + */ + private static function gcd(int $a, int $b) + { + while ($b != 0) { + $t = $b; + $b = $a % $b; + $a = $t; + } + + return $a; + } } -- 2.20.1