From 92e0788e9bb22e5e5339bdb8ac3f8d07dcc39ff7 Mon Sep 17 00:00:00 2001 From: ildyria Date: Sat, 3 Oct 2026 21:57:18 +0200 Subject: [PATCH 1/2] feat: expose XMP-GPano panorama tags Map XMP-GPano photo sphere tags in the Exiftool and ImageMagick mappers so consumers can detect equirectangular panoramas through Exif getters instead of raw data. New getters: getProjectionType (lower-cased), getUsePanoramaViewer (nullable bool), getFullPanoWidthPixels, getFullPanoHeightPixels, getCroppedAreaLeftPixels, getCroppedAreaTopPixels, getCroppedAreaImageWidthPixels, getCroppedAreaImageHeightPixels. Invalid boolean or non-numeric values are skipped. Native and FFprobe are unchanged. Also migrate the test suite from PHPUnit 9 to PHPUnit 11.5, 12 or 13 depending on the PHP version, using attributes, static data providers and the current mock API. --- .gitignore | 2 + composer.json | 3 +- lib/PHPExif/Exif.php | 226 +++++++++++++ lib/PHPExif/Mapper/AbstractMapper.php | 37 +++ lib/PHPExif/Mapper/Exiftool.php | 42 ++- lib/PHPExif/Mapper/ImageMagick.php | 42 ++- phpunit.xml.dist | 18 +- ...stractTest.php => AbstractAdapterTest.php} | 57 +--- .../PHPExif/Adapter/ExiftoolProcOpenTest.php | 5 +- tests/PHPExif/Adapter/ExiftoolTest.php | 62 ++-- tests/PHPExif/Adapter/FFprobeTest.php | 25 +- tests/PHPExif/Adapter/ImageMagickTest.php | 31 +- tests/PHPExif/Adapter/NativeTest.php | 53 +-- tests/PHPExif/ExifTest.php | 310 +++++++++--------- tests/PHPExif/Hydrator/MutatorTest.php | 19 +- tests/PHPExif/Mapper/ExiftoolMapperTest.php | 248 ++++++++------ tests/PHPExif/Mapper/FFprobeMapperTest.php | 80 ++--- .../PHPExif/Mapper/ImageMagickMapperTest.php | 218 +++++++----- tests/PHPExif/Mapper/NativeMapperTest.php | 105 ++---- tests/PHPExif/Reader/ReaderTest.php | 37 +-- tests/files/gpano.jpg | Bin 0 -> 203275 bytes 21 files changed, 969 insertions(+), 651 deletions(-) rename tests/PHPExif/Adapter/{AdapterAbstractTest.php => AbstractAdapterTest.php} (90%) create mode 100644 tests/files/gpano.jpg diff --git a/.gitignore b/.gitignore index 28fa55a6..9fbb44cb 100755 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ composer.phar .DS_Store .idea .phpunit.result.cache +.phpunit.cache +coverage.xml infection.html # Otherwise we won't be able to install it on different php version. composer.lock \ No newline at end of file diff --git a/composer.json b/composer.json index 93b4e2ae..e27c369a 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "lychee-org/phpstan-lychee": "^2.0.1|^1.0.0", "php-parallel-lint/php-parallel-lint": "^1.3.2", "phpmd/phpmd": "^2.15", - "phpunit/phpunit": "^9.5.10", + "phpunit/phpunit": "^11.5 || ^12.0 || ^13.0", "squizlabs/php_codesniffer": "^3.9", "thecodingmachine/phpstan-safe-rule": "^1.2" }, @@ -65,6 +65,7 @@ "vendor/bin/phpcs --standard=PSR2 ./lib/" ], "run-tests": [ + "@putenv XDEBUG_MODE=coverage", "vendor/bin/phpunit -c phpunit.xml.dist", "vendor/bin/phpunit --coverage-clover=coverage.xml" ], diff --git a/lib/PHPExif/Exif.php b/lib/PHPExif/Exif.php index 35536eb9..666657f3 100644 --- a/lib/PHPExif/Exif.php +++ b/lib/PHPExif/Exif.php @@ -26,6 +26,10 @@ class Exif public const COUNTRY = 'country'; public const CREATION_DATE = 'creationdate'; public const CREDIT = 'credit'; + public const CROPPEDAREAIMAGEHEIGHTPIXELS = 'CroppedAreaImageHeightPixels'; + public const CROPPEDAREAIMAGEWIDTHPIXELS = 'CroppedAreaImageWidthPixels'; + public const CROPPEDAREALEFTPIXELS = 'CroppedAreaLeftPixels'; + public const CROPPEDAREATOPPIXELS = 'CroppedAreaTopPixels'; public const DESCRIPTION = 'description'; public const DURATION = 'duration'; public const EXPOSURE = 'exposure'; @@ -34,6 +38,8 @@ class Exif public const FOCAL_LENGTH = 'focalLength'; public const FOCAL_DISTANCE = 'focalDistance'; public const FRAMERATE = 'framerate'; + public const FULLPANOHEIGHTPIXELS = 'FullPanoHeightPixels'; + public const FULLPANOWIDTHPIXELS = 'FullPanoWidthPixels'; public const GPS = 'gps'; public const HEADLINE = 'headline'; public const HEIGHT = 'height'; @@ -49,11 +55,13 @@ class Exif public const MICROVIDEOOFFSET = 'MicroVideoOffset'; public const MIMETYPE = 'MimeType'; public const ORIENTATION = 'Orientation'; + public const PROJECTIONTYPE = 'ProjectionType'; public const SOFTWARE = 'software'; public const SOURCE = 'source'; public const STATE = 'state'; public const SUBLOCATION = 'Sublocation'; public const TITLE = 'title'; + public const USEPANORAMAVIEWER = 'UsePanoramaViewer'; public const VERTICAL_RESOLUTION = 'verticalResolution'; public const WIDTH = 'width'; @@ -1174,6 +1182,224 @@ public function getMicroVideoOffset(): string|false return $this->data[self::MICROVIDEOOFFSET]; } + /** + * Sets the GPano projection type (lower-cased by the mappers) + * + * @param string $value + * @return Exif + */ + public function setProjectionType(string $value): Exif + { + $this->data[self::PROJECTIONTYPE] = $value; + + return $this; + } + + /** + * Returns the GPano projection type, if it exists + * e.g. "equirectangular" for a photo sphere + * + * @return string|false + */ + public function getProjectionType(): string|false + { + if (!isset($this->data[self::PROJECTIONTYPE])) { + return false; + } + + return $this->data[self::PROJECTIONTYPE]; + } + + /** + * Sets the GPano UsePanoramaViewer flag + * + * @param bool $value + * @return Exif + */ + public function setUsePanoramaViewer(bool $value): Exif + { + $this->data[self::USEPANORAMAVIEWER] = $value; + + return $this; + } + + /** + * Returns the GPano UsePanoramaViewer flag, or null if it does not exist. + * Unlike the other getters, false is a meaningful value here. + * + * @return bool|null + */ + public function getUsePanoramaViewer(): ?bool + { + if (!isset($this->data[self::USEPANORAMAVIEWER])) { + return null; + } + + return $this->data[self::USEPANORAMAVIEWER]; + } + + /** + * Sets the GPano full panorama width, in pixels + * + * @param int $value + * @return Exif + */ + public function setFullPanoWidthPixels(int $value): Exif + { + $this->data[self::FULLPANOWIDTHPIXELS] = $value; + + return $this; + } + + /** + * Returns the GPano full panorama width, in pixels, if it exists + * + * @return int|false + */ + public function getFullPanoWidthPixels(): int|false + { + if (!isset($this->data[self::FULLPANOWIDTHPIXELS])) { + return false; + } + + return $this->data[self::FULLPANOWIDTHPIXELS]; + } + + /** + * Sets the GPano full panorama height, in pixels + * + * @param int $value + * @return Exif + */ + public function setFullPanoHeightPixels(int $value): Exif + { + $this->data[self::FULLPANOHEIGHTPIXELS] = $value; + + return $this; + } + + /** + * Returns the GPano full panorama height, in pixels, if it exists + * + * @return int|false + */ + public function getFullPanoHeightPixels(): int|false + { + if (!isset($this->data[self::FULLPANOHEIGHTPIXELS])) { + return false; + } + + return $this->data[self::FULLPANOHEIGHTPIXELS]; + } + + /** + * Sets the GPano left offset of the cropped area, in pixels + * + * @param int $value + * @return Exif + */ + public function setCroppedAreaLeftPixels(int $value): Exif + { + $this->data[self::CROPPEDAREALEFTPIXELS] = $value; + + return $this; + } + + /** + * Returns the GPano left offset of the cropped area, in pixels, if it exists + * + * @return int|false + */ + public function getCroppedAreaLeftPixels(): int|false + { + if (!isset($this->data[self::CROPPEDAREALEFTPIXELS])) { + return false; + } + + return $this->data[self::CROPPEDAREALEFTPIXELS]; + } + + /** + * Sets the GPano top offset of the cropped area, in pixels + * + * @param int $value + * @return Exif + */ + public function setCroppedAreaTopPixels(int $value): Exif + { + $this->data[self::CROPPEDAREATOPPIXELS] = $value; + + return $this; + } + + /** + * Returns the GPano top offset of the cropped area, in pixels, if it exists + * + * @return int|false + */ + public function getCroppedAreaTopPixels(): int|false + { + if (!isset($this->data[self::CROPPEDAREATOPPIXELS])) { + return false; + } + + return $this->data[self::CROPPEDAREATOPPIXELS]; + } + + /** + * Sets the GPano cropped area width, in pixels + * + * @param int $value + * @return Exif + */ + public function setCroppedAreaImageWidthPixels(int $value): Exif + { + $this->data[self::CROPPEDAREAIMAGEWIDTHPIXELS] = $value; + + return $this; + } + + /** + * Returns the GPano cropped area width, in pixels, if it exists + * + * @return int|false + */ + public function getCroppedAreaImageWidthPixels(): int|false + { + if (!isset($this->data[self::CROPPEDAREAIMAGEWIDTHPIXELS])) { + return false; + } + + return $this->data[self::CROPPEDAREAIMAGEWIDTHPIXELS]; + } + + /** + * Sets the GPano cropped area height, in pixels + * + * @param int $value + * @return Exif + */ + public function setCroppedAreaImageHeightPixels(int $value): Exif + { + $this->data[self::CROPPEDAREAIMAGEHEIGHTPIXELS] = $value; + + return $this; + } + + /** + * Returns the GPano cropped area height, in pixels, if it exists + * + * @return int|false + */ + public function getCroppedAreaImageHeightPixels(): int|false + { + if (!isset($this->data[self::CROPPEDAREAIMAGEHEIGHTPIXELS])) { + return false; + } + + return $this->data[self::CROPPEDAREAIMAGEHEIGHTPIXELS]; + } + /** * Sets the sublocation value * diff --git a/lib/PHPExif/Mapper/AbstractMapper.php b/lib/PHPExif/Mapper/AbstractMapper.php index b8d1c139..4b40187c 100644 --- a/lib/PHPExif/Mapper/AbstractMapper.php +++ b/lib/PHPExif/Mapper/AbstractMapper.php @@ -34,4 +34,41 @@ public function trim(mixed $data): mixed } return $data; } + + /** + * Normalize a boolean XMP value: true/false (any case), 1/0 or a PHP bool + * + * @param mixed $value + * @return bool|null null if the value is not a recognised boolean + */ + protected function normalizeBool(mixed $value): ?bool + { + if (is_bool($value)) { + return $value; + } + if (!is_int($value) && !is_string($value)) { + return null; + } + + return match (strtolower(trim((string) $value))) { + 'true', '1' => true, + 'false', '0' => false, + default => null, + }; + } + + /** + * Normalize an integer value + * + * @param mixed $value + * @return int|null null if the value is not numeric + */ + protected function normalizeInt(mixed $value): ?int + { + if (!is_numeric($value)) { + return null; + } + + return (int) $value; + } } diff --git a/lib/PHPExif/Mapper/Exiftool.php b/lib/PHPExif/Mapper/Exiftool.php index f2e15a10..9f97f96a 100644 --- a/lib/PHPExif/Mapper/Exiftool.php +++ b/lib/PHPExif/Mapper/Exiftool.php @@ -100,6 +100,15 @@ class Exiftool extends AbstractMapper public const DURATION_WMV = 'ASF:SendDuration'; public const DATETIMEORIGINAL_PNG = 'PNG:CreationTime'; + public const PROJECTIONTYPE = 'XMP-GPano:ProjectionType'; + public const USEPANORAMAVIEWER = 'XMP-GPano:UsePanoramaViewer'; + public const FULLPANOWIDTHPIXELS = 'XMP-GPano:FullPanoWidthPixels'; + public const FULLPANOHEIGHTPIXELS = 'XMP-GPano:FullPanoHeightPixels'; + public const CROPPEDAREALEFTPIXELS = 'XMP-GPano:CroppedAreaLeftPixels'; + public const CROPPEDAREATOPPIXELS = 'XMP-GPano:CroppedAreaTopPixels'; + public const CROPPEDAREAIMAGEWIDTHPIXELS = 'XMP-GPano:CroppedAreaImageWidthPixels'; + public const CROPPEDAREAIMAGEHEIGHTPIXELS = 'XMP-GPano:CroppedAreaImageHeightPixels'; + /** * Maps the ExifTool fields to the fields of * the \PHPExif\Exif class @@ -175,7 +184,15 @@ class Exiftool extends AbstractMapper self::CITY => Exif::CITY, self::STATE => Exif::STATE, self::COUNTRY => Exif::COUNTRY, - self::DATETIMEORIGINAL_PNG => Exif::CREATION_DATE + self::DATETIMEORIGINAL_PNG => Exif::CREATION_DATE, + self::PROJECTIONTYPE => Exif::PROJECTIONTYPE, + self::USEPANORAMAVIEWER => Exif::USEPANORAMAVIEWER, + self::FULLPANOWIDTHPIXELS => Exif::FULLPANOWIDTHPIXELS, + self::FULLPANOHEIGHTPIXELS => Exif::FULLPANOHEIGHTPIXELS, + self::CROPPEDAREALEFTPIXELS => Exif::CROPPEDAREALEFTPIXELS, + self::CROPPEDAREATOPPIXELS => Exif::CROPPEDAREATOPPIXELS, + self::CROPPEDAREAIMAGEWIDTHPIXELS => Exif::CROPPEDAREAIMAGEWIDTHPIXELS, + self::CROPPEDAREAIMAGEHEIGHTPIXELS => Exif::CROPPEDAREAIMAGEHEIGHTPIXELS ); protected bool $numeric = true; @@ -386,6 +403,29 @@ public function mapRawData(array $data): array $mappedData[Exif::LENS] = $value; } continue 2; + case self::PROJECTIONTYPE: + if (!is_string($value) || $value === '') { + continue 2; + } + $value = strtolower($value); + break; + case self::USEPANORAMAVIEWER: + $value = $this->normalizeBool($value); + if ($value === null) { + continue 2; + } + break; + case self::FULLPANOWIDTHPIXELS: + case self::FULLPANOHEIGHTPIXELS: + case self::CROPPEDAREALEFTPIXELS: + case self::CROPPEDAREATOPPIXELS: + case self::CROPPEDAREAIMAGEWIDTHPIXELS: + case self::CROPPEDAREAIMAGEHEIGHTPIXELS: + $value = $this->normalizeInt($value); + if ($value === null) { + continue 2; + } + break; } // set end result $mappedData[$key] = $value; diff --git a/lib/PHPExif/Mapper/ImageMagick.php b/lib/PHPExif/Mapper/ImageMagick.php index bf0f60f3..114e02ed 100644 --- a/lib/PHPExif/Mapper/ImageMagick.php +++ b/lib/PHPExif/Mapper/ImageMagick.php @@ -61,6 +61,15 @@ class ImageMagick extends AbstractMapper public const STATE = 'iptc:state'; public const COUNTRY = 'iptc:country'; + public const PROJECTIONTYPE = 'GPano:ProjectionType'; + public const USEPANORAMAVIEWER = 'GPano:UsePanoramaViewer'; + public const FULLPANOWIDTHPIXELS = 'GPano:FullPanoWidthPixels'; + public const FULLPANOHEIGHTPIXELS = 'GPano:FullPanoHeightPixels'; + public const CROPPEDAREALEFTPIXELS = 'GPano:CroppedAreaLeftPixels'; + public const CROPPEDAREATOPPIXELS = 'GPano:CroppedAreaTopPixels'; + public const CROPPEDAREAIMAGEWIDTHPIXELS = 'GPano:CroppedAreaImageWidthPixels'; + public const CROPPEDAREAIMAGEHEIGHTPIXELS = 'GPano:CroppedAreaImageHeightPixels'; + /** * Maps the ExifTool fields to the fields of @@ -109,7 +118,15 @@ class ImageMagick extends AbstractMapper self::CITY => Exif::CITY, self::SUBLOCATION => Exif::SUBLOCATION, self::STATE => Exif::STATE, - self::COUNTRY => Exif::COUNTRY + self::COUNTRY => Exif::COUNTRY, + self::PROJECTIONTYPE => Exif::PROJECTIONTYPE, + self::USEPANORAMAVIEWER => Exif::USEPANORAMAVIEWER, + self::FULLPANOWIDTHPIXELS => Exif::FULLPANOWIDTHPIXELS, + self::FULLPANOHEIGHTPIXELS => Exif::FULLPANOHEIGHTPIXELS, + self::CROPPEDAREALEFTPIXELS => Exif::CROPPEDAREALEFTPIXELS, + self::CROPPEDAREATOPPIXELS => Exif::CROPPEDAREATOPPIXELS, + self::CROPPEDAREAIMAGEWIDTHPIXELS => Exif::CROPPEDAREAIMAGEWIDTHPIXELS, + self::CROPPEDAREAIMAGEHEIGHTPIXELS => Exif::CROPPEDAREAIMAGEHEIGHTPIXELS ); @@ -250,6 +267,29 @@ public function mapRawData(array $data): array $value = [$value]; } break; + case self::PROJECTIONTYPE: + if (!is_string($value) || $value === '') { + continue 2; + } + $value = strtolower($value); + break; + case self::USEPANORAMAVIEWER: + $value = $this->normalizeBool($value); + if ($value === null) { + continue 2; + } + break; + case self::FULLPANOWIDTHPIXELS: + case self::FULLPANOHEIGHTPIXELS: + case self::CROPPEDAREALEFTPIXELS: + case self::CROPPEDAREATOPPIXELS: + case self::CROPPEDAREAIMAGEWIDTHPIXELS: + case self::CROPPEDAREAIMAGEHEIGHTPIXELS: + $value = $this->normalizeInt($value); + if ($value === null) { + continue 2; + } + break; } // set end result $mappedData[$key] = $value; diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c6794d34..6ba42007 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,6 @@ - + - - ./lib - - - ./autoload.php - *Interface.php - @@ -20,4 +13,13 @@ + + + ./lib + + + ./autoload.php + *Interface.php + + diff --git a/tests/PHPExif/Adapter/AdapterAbstractTest.php b/tests/PHPExif/Adapter/AbstractAdapterTest.php similarity index 90% rename from tests/PHPExif/Adapter/AdapterAbstractTest.php rename to tests/PHPExif/Adapter/AbstractAdapterTest.php index 8d034170..a8b1e165 100644 --- a/tests/PHPExif/Adapter/AdapterAbstractTest.php +++ b/tests/PHPExif/Adapter/AbstractAdapterTest.php @@ -3,6 +3,7 @@ use PHPExif\Adapter\AbstractAdapter; use PHPExif\Adapter\Exiftool; use PHPExif\Adapter\Native; +use PHPUnit\Framework\Attributes\Group; class AbstractAdapterTest extends PHPUnit\Framework\TestCase { @@ -16,18 +17,14 @@ protected function setUp(): void $this->adapter = new Native(); } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetOptionsReturnsCurrentInstance() { $result = $this->adapter->setOptions([]); $this->assertSame($this->adapter, $result); } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetOptionsCorrectlySetsProperties() { $expected = array( @@ -43,9 +40,7 @@ public function testSetOptionsCorrectlySetsProperties() } } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetOptionsIgnoresPropertiesWithoutSetters() { $expected = array( @@ -60,9 +55,7 @@ public function testSetOptionsIgnoresPropertiesWithoutSetters() } - /** - * @group adapter - */ + #[Group('adapter')] public function testConstructorSetsOptions() { $expected = array( @@ -78,9 +71,7 @@ public function testConstructorSetsOptions() } } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetMapperReturnsCurrentInstance() { $mapper = new \PHPExif\Mapper\Native(); @@ -88,9 +79,7 @@ public function testSetMapperReturnsCurrentInstance() $this->assertSame($this->adapter, $result); } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetMapperCorrectlySetsInProperty() { $mapper = new \PHPExif\Mapper\Native(); @@ -100,9 +89,7 @@ public function testSetMapperCorrectlySetsInProperty() $this->assertSame($mapper, $reflProp->getValue($this->adapter)); } - /** - * @group adapter - */ + #[Group('adapter')] public function testGetMapperCorrectlyReturnsFromProperty() { $mapper = new \PHPExif\Mapper\Native(); @@ -111,9 +98,7 @@ public function testGetMapperCorrectlyReturnsFromProperty() $this->assertSame($mapper, $this->adapter->getMapper()); } - /** - * @group adapter - */ + #[Group('adapter')] public function testGetMapperLazyLoadsMapperWhenNotPresent() { $reflProp = new \ReflectionProperty( @@ -127,9 +112,7 @@ public function testGetMapperLazyLoadsMapperWhenNotPresent() $this->assertInstanceOf($mapperClass, $this->adapter->getMapper()); } - /** - * @group adapter - */ + #[Group('adapter')] public function testGetMapperLazyLoadingSetsInProperty() { $reflProp = new \ReflectionProperty( @@ -148,9 +131,7 @@ public function testGetMapperLazyLoadingSetsInProperty() $this->assertInstanceOf($mapperClass, $reflProp2->getValue($this->adapter)); } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetHydratorReturnsCurrentInstance() { $hydrator = new \PHPExif\Hydrator\Mutator(); @@ -158,9 +139,7 @@ public function testSetHydratorReturnsCurrentInstance() $this->assertSame($this->adapter, $result); } - /** - * @group adapter - */ + #[Group('adapter')] public function testSetHydratorCorrectlySetsInProperty() { $hydrator = new \PHPExif\Hydrator\Mutator(); @@ -170,9 +149,7 @@ public function testSetHydratorCorrectlySetsInProperty() $this->assertSame($hydrator, $reflProp->getValue($this->adapter)); } - /** - * @group adapter - */ + #[Group('adapter')] public function testGetHydratorCorrectlyReturnsFromProperty() { $hydrator = new \PHPExif\Hydrator\Mutator(); @@ -181,18 +158,14 @@ public function testGetHydratorCorrectlyReturnsFromProperty() $this->assertSame($hydrator, $this->adapter->getHydrator()); } - /** - * @group adapter - */ + #[Group('adapter')] public function testGetHydratorLazyLoadsHydratorWhenNotPresent() { $hydratorClass = '\\PHPExif\\Hydrator\\Mutator'; $this->assertInstanceOf($hydratorClass, $this->adapter->getHydrator()); } - /** - * @group adapter - */ + #[Group('adapter')] public function testGetHydratorLazyLoadingSetsInProperty() { $hydratorClass = '\\PHPExif\\Hydrator\\Mutator'; diff --git a/tests/PHPExif/Adapter/ExiftoolProcOpenTest.php b/tests/PHPExif/Adapter/ExiftoolProcOpenTest.php index c5cc8133..a5d41419 100644 --- a/tests/PHPExif/Adapter/ExiftoolProcOpenTest.php +++ b/tests/PHPExif/Adapter/ExiftoolProcOpenTest.php @@ -14,6 +14,7 @@ // stub the function use PHPExif\Reader\PhpExifReaderException; + use PHPUnit\Framework\Attributes\Group; function proc_open($cmd, array $descriptorspec, &$pipes = []) { @@ -48,9 +49,7 @@ public function tearDown(): void $mockProcOpen = false; } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetCliOutput() { $this->expectException(PhpExifReaderException::class); diff --git a/tests/PHPExif/Adapter/ExiftoolTest.php b/tests/PHPExif/Adapter/ExiftoolTest.php index 53b603be..97dbbcc7 100644 --- a/tests/PHPExif/Adapter/ExiftoolTest.php +++ b/tests/PHPExif/Adapter/ExiftoolTest.php @@ -1,6 +1,7 @@ adapter = new Exiftool(); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetToolPathFromProperty() { $reflProperty = new \ReflectionProperty(Exiftool::class, 'toolPath'); @@ -23,9 +22,7 @@ public function testGetToolPathFromProperty() $this->assertEquals($expected, $this->adapter->getToolPath()); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testSetToolPathInProperty() { $reflProperty = new \ReflectionProperty(Exiftool::class, 'toolPath'); @@ -36,9 +33,7 @@ public function testSetToolPathInProperty() $this->assertEquals($expected, $reflProperty->getValue($this->adapter)); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testSetToolPathThrowsException() { $this->expectException('InvalidArgumentException'); @@ -46,17 +41,13 @@ public function testSetToolPathThrowsException() } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetToolPathLazyLoadsPath() { $this->assertIsString($this->adapter->getToolPath()); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testSetNumericInProperty() { $reflProperty = new \ReflectionProperty(Exiftool::class, 'numeric'); @@ -69,8 +60,8 @@ public function testSetNumericInProperty() /** * @see URI http://www.sno.phy.queensu.ca/~phil/exiftool/faq.html#Q10 - * @group exiftool */ + #[Group('exiftool')] public function testSetEncodingInProperty() { $reflProperty = new \ReflectionProperty(Exiftool::class, 'encoding'); @@ -82,9 +73,7 @@ public function testSetEncodingInProperty() $this->assertEquals($expected, $reflProperty->getValue($this->adapter)); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetExifFromFile() { $file = PHPEXIF_TEST_ROOT . '/files/morning_glory_pool_500.jpg'; @@ -95,9 +84,7 @@ public function testGetExifFromFile() $this->assertNotEmpty($result->getRawData()); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetExifFromFileWithUtf8() { $file = PHPEXIF_TEST_ROOT . '/files/utf8.jpg'; @@ -108,9 +95,7 @@ public function testGetExifFromFileWithUtf8() $this->assertNotEmpty($result->getRawData()); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetExifFromFileWithAvif() { $file = PHPEXIF_TEST_ROOT . '/files/fox.profile0.10bpc.yuv420.avif'; @@ -121,9 +106,7 @@ public function testGetExifFromFileWithAvif() $this->assertNotEmpty($result->getRawData()); } - /** - * @group exiftool - */ + #[Group('exiftool')] public function testGetCliOutput() { $reflMethod = new \ReflectionMethod(Exiftool::class, 'getCliOutput'); @@ -138,4 +121,27 @@ public function testGetCliOutput() $this->assertIsString($result); } + + /** + * Reads the XMP-GPano tags of a photo sphere. ImageMagickTest asserts the + * same values, so both adapters return identical getter values. + */ + #[Group('exiftool')] + public function testGetPanoramaDataFromFile() + { + if ($this->adapter->getToolPath() === '') { + $this->markTestSkipped('exiftool is not available.'); + } + $file = PHPEXIF_TEST_ROOT . '/files/gpano.jpg'; + $result = $this->adapter->getExifFromFile($file); + + $this->assertSame('equirectangular', $result->getProjectionType()); + $this->assertSame(true, $result->getUsePanoramaViewer()); + $this->assertSame(8000, $result->getFullPanoWidthPixels()); + $this->assertSame(4000, $result->getFullPanoHeightPixels()); + $this->assertSame(1000, $result->getCroppedAreaLeftPixels()); + $this->assertSame(1000, $result->getCroppedAreaTopPixels()); + $this->assertSame(6000, $result->getCroppedAreaImageWidthPixels()); + $this->assertSame(2000, $result->getCroppedAreaImageHeightPixels()); + } } diff --git a/tests/PHPExif/Adapter/FFprobeTest.php b/tests/PHPExif/Adapter/FFprobeTest.php index 146fb614..50b10680 100644 --- a/tests/PHPExif/Adapter/FFprobeTest.php +++ b/tests/PHPExif/Adapter/FFprobeTest.php @@ -3,6 +3,7 @@ use PHPExif\Adapter\FFprobe; use PHPExif\Exif; use PHPExif\Reader\PhpExifReaderException; +use PHPUnit\Framework\Attributes\Group; class FFprobeTest extends \PHPUnit\Framework\TestCase { @@ -17,9 +18,7 @@ public function setUp(): void } - /** - * @group ffprobe - */ + #[Group('ffprobe')] public function testGetToolPathFromProperty() { $reflProperty = new \ReflectionProperty(FFprobe::class, 'toolPath'); @@ -29,9 +28,7 @@ public function testGetToolPathFromProperty() $this->assertEquals($expected, $this->adapter->getToolPath()); } - /** - * @group ffprobe - */ + #[Group('ffprobe')] public function testSetToolPathInProperty() { $reflProperty = new \ReflectionProperty(FFprobe::class, 'toolPath'); @@ -42,26 +39,20 @@ public function testSetToolPathInProperty() $this->assertEquals($expected, $reflProperty->getValue($this->adapter)); } - /** - * @group ffprobe - */ + #[Group('ffprobe')] public function testSetToolPathThrowsException() { $this->expectException('InvalidArgumentException'); $this->adapter->setToolPath('/foo/bar'); } - /** - * @group ffprobe - */ + #[Group('ffprobe')] public function testGetToolPathLazyLoadsPath() { $this->assertIsString($this->adapter->getToolPath()); } - /** - * @group ffprobe - */ + #[Group('ffprobe')] public function testGetExifFromFileHasData() { $file = PHPEXIF_TEST_ROOT . '/files/IMG_3824.MOV'; @@ -77,9 +68,7 @@ public function testGetExifFromFileHasData() $this->assertNotEmpty($result->getRawData()); } - /** - * @group ffprobe - */ + #[Group('ffprobe')] public function testErrorImageUsed() { $file = PHPEXIF_TEST_ROOT . '/files/morning_glory_pool_500.jpg'; diff --git a/tests/PHPExif/Adapter/ImageMagickTest.php b/tests/PHPExif/Adapter/ImageMagickTest.php index f8647128..b313027f 100644 --- a/tests/PHPExif/Adapter/ImageMagickTest.php +++ b/tests/PHPExif/Adapter/ImageMagickTest.php @@ -2,6 +2,7 @@ use PHPExif\Adapter\ImageMagick; use PHPExif\Exif; +use PHPUnit\Framework\Attributes\Group; class ImageMagickTest extends \PHPUnit\Framework\TestCase { @@ -15,9 +16,7 @@ public function setUp(): void $this->adapter = new ImageMagick(); } - /** - * @group ImageMagick - */ + #[Group('ImageMagick')] public function testGetExifFromFile() { $file = PHPEXIF_TEST_ROOT . '/files/morning_glory_pool_500.jpg'; @@ -27,9 +26,7 @@ public function testGetExifFromFile() $this->assertNotEmpty($result->getRawData()); } - /** - * @group ImageMagick - */ + #[Group('ImageMagick')] public function testGetEmptyIptcData() { $result = $this->adapter->getIptcData(""); @@ -37,4 +34,26 @@ public function testGetEmptyIptcData() $this->assertEquals([], $result); } + /** + * Reads the XMP-GPano tags of a photo sphere. ExiftoolTest asserts the + * same values, so both adapters return identical getter values. + */ + #[Group('ImageMagick')] + public function testGetPanoramaDataFromFile() + { + if (!extension_loaded('imagick')) { + $this->markTestSkipped('The imagick extension is not available.'); + } + $file = PHPEXIF_TEST_ROOT . '/files/gpano.jpg'; + $result = $this->adapter->getExifFromFile($file); + + $this->assertSame('equirectangular', $result->getProjectionType()); + $this->assertSame(true, $result->getUsePanoramaViewer()); + $this->assertSame(8000, $result->getFullPanoWidthPixels()); + $this->assertSame(4000, $result->getFullPanoHeightPixels()); + $this->assertSame(1000, $result->getCroppedAreaLeftPixels()); + $this->assertSame(1000, $result->getCroppedAreaTopPixels()); + $this->assertSame(6000, $result->getCroppedAreaImageWidthPixels()); + $this->assertSame(2000, $result->getCroppedAreaImageHeightPixels()); + } } diff --git a/tests/PHPExif/Adapter/NativeTest.php b/tests/PHPExif/Adapter/NativeTest.php index aa211e8f..106ce162 100644 --- a/tests/PHPExif/Adapter/NativeTest.php +++ b/tests/PHPExif/Adapter/NativeTest.php @@ -1,6 +1,7 @@ adapter = new Native(); } - /** - * @group native - */ + #[Group('native')] public function testSetIncludeThumbnailInProperty() { $reflProperty = new \ReflectionProperty(Native::class, 'includeThumbnail'); @@ -28,9 +27,7 @@ public function testSetIncludeThumbnailInProperty() $this->assertEquals(Native::INCLUDE_THUMBNAIL, $reflProperty->getValue($this->adapter)); } - /** - * @group native - */ + #[Group('native')] public function testGetIncludeThumbnailFromProperty() { $reflProperty = new \ReflectionProperty(Native::class, 'includeThumbnail'); @@ -39,17 +36,13 @@ public function testGetIncludeThumbnailFromProperty() $this->assertEquals(Native::INCLUDE_THUMBNAIL, $this->adapter->getIncludeThumbnail()); } - /** - * @group native - */ + #[Group('native')] public function testGetIncludeThumbnailHasDefaultValue() { $this->assertEquals(Native::NO_THUMBNAIL, $this->adapter->getIncludeThumbnail()); } - /** - * @group native - */ + #[Group('native')] public function testGetRequiredSections() { $reflProperty = new \ReflectionProperty(Native::class, 'requiredSections'); @@ -57,9 +50,7 @@ public function testGetRequiredSections() $this->assertEquals($reflProperty->getValue($this->adapter), $this->adapter->getRequiredSections()); } - /** - * @group native - */ + #[Group('native')] public function testSetRequiredSections() { $reflProperty = new \ReflectionProperty(Native::class, 'requiredSections'); @@ -72,9 +63,7 @@ public function testSetRequiredSections() $this->assertEquals($this->adapter, $returnValue); } - /** - * @group native - */ + #[Group('native')] public function testAddRequiredSection() { $reflProperty = new \ReflectionProperty(Native::class, 'requiredSections'); @@ -89,9 +78,7 @@ public function testAddRequiredSection() $this->assertEquals($this->adapter, $returnValue); } - /** - * @group native - */ + #[Group('native')] public function testGetExifFromFileNoData() { $file = PHPEXIF_TEST_ROOT . '/files/empty.jpg'; @@ -102,9 +89,7 @@ public function testGetExifFromFileNoData() $this->assertEquals($expected, $result->getRawData()); } - /** - * @group native - */ + #[Group('native')] public function testGetExifFromFileHasData() { $file = PHPEXIF_TEST_ROOT . '/files/morning_glory_pool_500.jpg'; @@ -114,9 +99,7 @@ public function testGetExifFromFileHasData() $this->assertNotEmpty($result->getRawData()); } - /** - * @group native - */ + #[Group('native')] public function testGetIptcData() { $file = PHPEXIF_TEST_ROOT . '/files/morning_glory_pool_500.jpg'; @@ -131,9 +114,7 @@ public function testGetIptcData() $this->assertEquals($expected, $result); } - /** - * @group native - */ + #[Group('native')] public function testGetEmptyIptcData() { $file = PHPEXIF_TEST_ROOT . '/files/empty_iptc.jpg'; @@ -142,9 +123,7 @@ public function testGetEmptyIptcData() $this->assertEquals([], $result); } - /** - * @group native - */ + #[Group('native')] public function testSetSectionsAsArrayInProperty() { $reflProperty = new \ReflectionProperty(Native::class, 'sectionsAsArrays'); @@ -154,9 +133,7 @@ public function testSetSectionsAsArrayInProperty() $this->assertEquals($expected, $actual); } - /** - * @group native - */ + #[Group('native')] public function testSetSectionsAsArrayConvertsToBoolean() { $reflProperty = new \ReflectionProperty(Native::class, 'sectionsAsArrays'); @@ -166,9 +143,7 @@ public function testSetSectionsAsArrayConvertsToBoolean() $this->assertEquals($expected, $actual); } - /** - * @group native - */ + #[Group('native')] public function testGetSectionsAsArrayFromProperty() { $reflProperty = new \ReflectionProperty(Native::class, 'sectionsAsArrays'); diff --git a/tests/PHPExif/ExifTest.php b/tests/PHPExif/ExifTest.php index ad920c79..eb8f319b 100644 --- a/tests/PHPExif/ExifTest.php +++ b/tests/PHPExif/ExifTest.php @@ -1,6 +1,8 @@ exif = new Exif(); } - /** - * @group exif - */ + #[Group('exif')] public function testConstructorCallsSetData() { $input = []; @@ -42,9 +42,7 @@ public function testConstructorCallsSetData() $constructor->invoke($mock, $input); } - /** - * @group exif - */ + #[Group('exif')] public function testGetRawData() { $reflProperty = new \ReflectionProperty(Exif::class, 'rawData'); @@ -52,9 +50,7 @@ public function testGetRawData() $this->assertEquals($reflProperty->getValue($this->exif), $this->exif->getRawData()); } - /** - * @group exif - */ + #[Group('exif')] public function testSetRawData() { $testData = array('foo', 'bar', 'baz'); @@ -66,9 +62,7 @@ public function testSetRawData() $this->assertEquals($this->exif, $result); } - /** - * @group exif - */ + #[Group('exif')] public function testGetData() { $reflProperty = new \ReflectionProperty(Exif::class, 'data'); @@ -76,9 +70,7 @@ public function testGetData() $this->assertEquals($reflProperty->getValue($this->exif), $this->exif->getData()); } - /** - * @group exif - */ + #[Group('exif')] public function testSetData() { $testData = array('foo', 'bar', 'baz'); @@ -92,9 +84,9 @@ public function testSetData() /** * - * @dataProvider providerUndefinedPropertiesReturnFalse * @param string $accessor */ + #[DataProvider('providerUndefinedPropertiesReturnFalse')] public function testUndefinedPropertiesReturnFalse($accessor) { $expected = false; @@ -106,7 +98,7 @@ public function testUndefinedPropertiesReturnFalse($accessor) * * @return array */ - public function providerUndefinedPropertiesReturnFalse() + public static function providerUndefinedPropertiesReturnFalse() { return array( array('getAperture'), @@ -153,12 +145,26 @@ public function providerUndefinedPropertiesReturnFalse() array('getSublocation'), array('getState'), array('getCountry'), + array('getProjectionType'), + array('getFullPanoWidthPixels'), + array('getFullPanoHeightPixels'), + array('getCroppedAreaLeftPixels'), + array('getCroppedAreaTopPixels'), + array('getCroppedAreaImageWidthPixels'), + array('getCroppedAreaImageHeightPixels'), ); } /** - * @group exif + * UsePanoramaViewer distinguishes "absent" (null) from an explicit false */ + #[Group('exif')] + public function testUndefinedUsePanoramaViewerReturnsNull() + { + $this->assertNull($this->exif->getUsePanoramaViewer()); + } + + #[Group('exif')] public function testGetAperture() { $expected = 'f/8.0'; @@ -168,9 +174,7 @@ public function testGetAperture() $this->assertEquals($expected, $this->exif->getAperture()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetIso() { $expected = 200; @@ -179,9 +183,7 @@ public function testGetIso() $this->assertEquals($expected, $this->exif->getIso()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetExposure() { $expected = '1/320'; @@ -190,9 +192,7 @@ public function testGetExposure() $this->assertEquals($expected, $this->exif->getExposure()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetExposureMilliseconds() { $rawData = array( @@ -210,9 +210,7 @@ public function testGetExposureMilliseconds() } } - /** - * @group exif - */ + #[Group('exif')] public function testGetFocusDistance() { $expected = '7.94m'; @@ -221,9 +219,7 @@ public function testGetFocusDistance() $this->assertEquals($expected, $this->exif->getFocusDistance()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetWidth() { $expected = 500; @@ -232,9 +228,7 @@ public function testGetWidth() $this->assertEquals($expected, $this->exif->getWidth()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetHeight() { $expected = 332; @@ -243,9 +237,7 @@ public function testGetHeight() $this->assertEquals($expected, $this->exif->getHeight()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetTitle() { $expected = 'Morning Glory Pool'; @@ -254,9 +246,7 @@ public function testGetTitle() $this->assertEquals($expected, $this->exif->getTitle()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCaption() { $expected = 'Foo Bar Baz'; @@ -265,9 +255,7 @@ public function testGetCaption() $this->assertEquals($expected, $this->exif->getCaption()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCopyright() { $expected = 'Miljar'; @@ -276,9 +264,7 @@ public function testGetCopyright() $this->assertEquals($expected, $this->exif->getCopyright()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetKeywords() { $expected = array('18-200', 'D90', 'USA', 'Wyoming', 'Yellowstone'); @@ -287,9 +273,7 @@ public function testGetKeywords() $this->assertEquals($expected, $this->exif->getKeywords()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCamera() { $expected = 'NIKON D90'; @@ -298,9 +282,7 @@ public function testGetCamera() $this->assertEquals($expected, $this->exif->getCamera()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetHorizontalResolution() { $expected = 240; @@ -309,9 +291,7 @@ public function testGetHorizontalResolution() $this->assertEquals($expected, $this->exif->getHorizontalResolution()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetVerticalResolution() { $expected = 240; @@ -320,9 +300,7 @@ public function testGetVerticalResolution() $this->assertEquals($expected, $this->exif->getVerticalResolution()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetSoftware() { $expected = 'Adobe Photoshop Lightroom'; @@ -331,9 +309,7 @@ public function testGetSoftware() $this->assertEquals($expected, $this->exif->getSoftware()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetFocalLength() { $expected = 18; @@ -342,9 +318,7 @@ public function testGetFocalLength() $this->assertEquals($expected, $this->exif->getFocalLength()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCreationDate() { $expected = '2011-06-07 20:01:50'; @@ -354,9 +328,7 @@ public function testGetCreationDate() $this->assertEquals($expected, $this->exif->getCreationDate()->format('Y-m-d H:i:s')); } - /** - * @group exif - */ + #[Group('exif')] public function testGetAuthor() { $expected = 'John Smith'; @@ -365,9 +337,7 @@ public function testGetAuthor() $this->assertEquals($expected, $this->exif->getAuthor()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetHeadline() { $expected = 'Foobar Baz'; @@ -376,9 +346,7 @@ public function testGetHeadline() $this->assertEquals($expected, $this->exif->getHeadline()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCredit() { $expected = 'john.smith@example.com'; @@ -387,9 +355,7 @@ public function testGetCredit() $this->assertEquals($expected, $this->exif->getCredit()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetSource() { $expected = 'FBB NEWS'; @@ -398,9 +364,7 @@ public function testGetSource() $this->assertEquals($expected, $this->exif->getSource()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetJobtitle() { $expected = 'Yellowstone\'s geysers and pools'; @@ -409,9 +373,7 @@ public function testGetJobtitle() $this->assertEquals($expected, $this->exif->getJobtitle()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetColorSpace() { $expected = 'RGB'; @@ -420,9 +382,7 @@ public function testGetColorSpace() $this->assertEquals($expected, $this->exif->getColorSpace()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetMimeType() { $expected = 'image/jpeg'; @@ -431,9 +391,7 @@ public function testGetMimeType() $this->assertEquals($expected, $this->exif->getMimeType()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetFileSize() { $expected = '27852365'; @@ -442,9 +400,7 @@ public function testGetFileSize() $this->assertEquals($expected, $this->exif->getFileSize()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetFileName() { $expected = '27852365.jpg'; @@ -453,9 +409,7 @@ public function testGetFileName() $this->assertEquals($expected, $this->exif->getFileName()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetOrientation() { $expected = 1; @@ -464,9 +418,7 @@ public function testGetOrientation() $this->assertEquals($expected, $this->exif->getOrientation()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetGPS() { $expected = '40.333452380556,-20.167314813889'; @@ -475,9 +427,7 @@ public function testGetGPS() $this->assertEquals($expected, $this->exif->getGPS()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetDescription() { $expected = 'Lorem ipsum'; @@ -486,9 +436,7 @@ public function testGetDescription() $this->assertEquals($expected, $this->exif->getDescription()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetMake() { $expected = 'Make'; @@ -497,9 +445,7 @@ public function testGetMake() $this->assertEquals($expected, $this->exif->getMake()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetAltitude() { $expected = '8848'; @@ -508,9 +454,7 @@ public function testGetAltitude() $this->assertEquals($expected, $this->exif->getAltitude()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetLatitude() { $expected = '40.333452380556'; @@ -519,9 +463,7 @@ public function testGetLatitude() $this->assertEquals($expected, $this->exif->getLatitude()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetLongitude() { $expected = '-20.167314813889'; @@ -530,9 +472,7 @@ public function testGetLongitude() $this->assertEquals($expected, $this->exif->getLongitude()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetImgDirection() { $expected = '180'; @@ -541,9 +481,7 @@ public function testGetImgDirection() $this->assertEquals($expected, $this->exif->getImgDirection()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetLens() { $expected = '70 - 200mm'; @@ -552,9 +490,7 @@ public function testGetLens() $this->assertEquals($expected, $this->exif->getLens()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetContentIdentifier() { $expected = 'C09DCB26-D321-4254-9F68-2E2E7FA16155'; @@ -563,9 +499,7 @@ public function testGetContentIdentifier() $this->assertEquals($expected, $this->exif->getContentIdentifier()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetFramerate() { $expected = '24'; @@ -574,9 +508,7 @@ public function testGetFramerate() $this->assertEquals($expected, $this->exif->getFramerate()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetDuration() { $expected = '1s'; @@ -585,9 +517,7 @@ public function testGetDuration() $this->assertEquals($expected, $this->exif->getDuration()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetMicroVideoOffset() { $expected = '3062730'; @@ -596,9 +526,7 @@ public function testGetMicroVideoOffset() $this->assertEquals($expected, $this->exif->getMicroVideoOffset()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCity() { $expected = 'New York'; @@ -607,9 +535,7 @@ public function testGetCity() $this->assertEquals($expected, $this->exif->getCity()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetSublocation() { $expected = 'sublocation'; @@ -618,9 +544,7 @@ public function testGetSublocation() $this->assertEquals($expected, $this->exif->getSublocation()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetState() { $expected = 'New York'; @@ -629,9 +553,7 @@ public function testGetState() $this->assertEquals($expected, $this->exif->getState()); } - /** - * @group exif - */ + #[Group('exif')] public function testGetCountry() { $expected = 'USA'; @@ -640,9 +562,88 @@ public function testGetCountry() $this->assertEquals($expected, $this->exif->getCountry()); } + #[Group('exif')] + public function testGetProjectionType() + { + $expected = 'equirectangular'; + $data[Exif::PROJECTIONTYPE] = $expected; + $this->exif->setData($data); + $this->assertSame($expected, $this->exif->getProjectionType()); + } + + #[Group('exif')] + public function testGetUsePanoramaViewer() + { + foreach (array(true, false) as $expected) { + $data[Exif::USEPANORAMAVIEWER] = $expected; + $this->exif->setData($data); + $this->assertSame($expected, $this->exif->getUsePanoramaViewer()); + } + } + /** - * @group exif + * Data provider for the integer GPano crop fields + * + * @return array */ + public static function providerPanoCropFields() + { + return array( + array(Exif::FULLPANOWIDTHPIXELS, 'FullPanoWidthPixels', 8000), + array(Exif::FULLPANOHEIGHTPIXELS, 'FullPanoHeightPixels', 4000), + array(Exif::CROPPEDAREALEFTPIXELS, 'CroppedAreaLeftPixels', 1000), + array(Exif::CROPPEDAREATOPPIXELS, 'CroppedAreaTopPixels', 0), + array(Exif::CROPPEDAREAIMAGEWIDTHPIXELS, 'CroppedAreaImageWidthPixels', 6000), + array(Exif::CROPPEDAREAIMAGEHEIGHTPIXELS, 'CroppedAreaImageHeightPixels', 2000), + ); + } + + #[Group('exif')] + #[DataProvider('providerPanoCropFields')] + public function testGetPanoCropFields($constant, $name, $expected) + { + $data[$constant] = $expected; + $this->exif->setData($data); + $getter = 'get' . $name; + $this->assertSame($expected, $this->exif->$getter()); + } + + #[Group('exif')] + #[DataProvider('providerPanoCropFields')] + public function testSetPanoCropFields($constant, $name, $expected) + { + $setter = 'set' . $name; + $getter = 'get' . $name; + $result = $this->exif->$setter($expected); + + $this->assertSame($this->exif, $result); + $this->assertSame($expected, $this->exif->$getter()); + $this->assertSame(array($constant => $expected), $this->exif->getData()); + } + + #[Group('exif')] + public function testSetProjectionType() + { + $result = $this->exif->setProjectionType('equirectangular'); + + $this->assertSame($this->exif, $result); + $this->assertSame('equirectangular', $this->exif->getProjectionType()); + $this->assertSame(array(Exif::PROJECTIONTYPE => 'equirectangular'), $this->exif->getData()); + } + + #[Group('exif')] + public function testSetUsePanoramaViewer() + { + foreach (array(true, false) as $expected) { + $result = $this->exif->setUsePanoramaViewer($expected); + + $this->assertSame($this->exif, $result); + $this->assertSame($expected, $this->exif->getUsePanoramaViewer()); + $this->assertSame(array(Exif::USEPANORAMAVIEWER => $expected), $this->exif->getData()); + } + } + + #[Group('exif')] public function testMutatorMethodsSetInProperty() { $reflClass = new \ReflectionClass(get_class($this->exif)); @@ -683,6 +684,22 @@ public function testMutatorMethodsSetInProperty() $propertyValue = $reflProp->getValue($this->exif); $this->assertEquals($coords, $propertyValue[$value]); break; + case 'FullPanoWidthPixels': + case 'FullPanoHeightPixels': + case 'CroppedAreaLeftPixels': + case 'CroppedAreaTopPixels': + case 'CroppedAreaImageWidthPixels': + case 'CroppedAreaImageHeightPixels': + $pixels = 1234; + $this->exif->$setter($pixels); + $propertyValue = $reflProp->getValue($this->exif); + $this->assertSame($pixels, $propertyValue[$value]); + break; + case 'UsePanoramaViewer': + $this->exif->$setter(false); + $propertyValue = $reflProp->getValue($this->exif); + $this->assertSame(false, $propertyValue[$value]); + break; case 'focalDistance': $setter = 'setFocusDistance'; // no break @@ -697,9 +714,8 @@ public function testMutatorMethodsSetInProperty() /** * Test that the values returned by different adapters are equal - * - * @group consistency */ + #[Group('consistency')] public function testAdapterConsistency() { $reflClass = new \ReflectionClass(Exif::class); diff --git a/tests/PHPExif/Hydrator/MutatorTest.php b/tests/PHPExif/Hydrator/MutatorTest.php index a267b72d..1664103c 100644 --- a/tests/PHPExif/Hydrator/MutatorTest.php +++ b/tests/PHPExif/Hydrator/MutatorTest.php @@ -1,6 +1,7 @@ expects($this->exactly(count($input))) ->method('determineMutator') - ->will($this->returnValue('setFoo')); + ->willReturn('setFoo'); $object = new TestClass(); @@ -36,9 +35,7 @@ public function testHydrateCallsDetermineMutator() $mock->hydrate($object, $input); } - /** - * @group hydrator - */ + #[Group('hydrator')] public function testHydrateCallsMutatorsOnObject() { // input data @@ -48,7 +45,7 @@ public function testHydrateCallsMutatorsOnObject() // create mock $mock = $this->getMockBuilder('TestClass') - ->setMethods(array('setBar')) + ->onlyMethods(array('setBar')) ->getMock(); $mock->expects($this->once()) @@ -60,9 +57,7 @@ public function testHydrateCallsMutatorsOnObject() $hydrator->hydrate($mock, $input); } - /** - * @group hydrator - */ + #[Group('hydrator')] public function testHydrateCallsEmptyValues() { // input data diff --git a/tests/PHPExif/Mapper/ExiftoolMapperTest.php b/tests/PHPExif/Mapper/ExiftoolMapperTest.php index 8a3de577..c2dc70cf 100644 --- a/tests/PHPExif/Mapper/ExiftoolMapperTest.php +++ b/tests/PHPExif/Mapper/ExiftoolMapperTest.php @@ -1,7 +1,10 @@ mapper = new Exiftool(); } - /** - * @group mapper - */ + #[Group('mapper')] public function testClassImplementsCorrectInterface() { $this->assertInstanceOf(MapperInterface::class, $this->mapper); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataIgnoresFieldIfItDoesntExist() { $rawData = array('foo' => 'bar'); @@ -31,9 +30,7 @@ public function testMapRawDataIgnoresFieldIfItDoesntExist() $this->assertCount(0, $mapped); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataMapsFieldsCorrectly() { $reflProp = new \ReflectionProperty(get_class($this->mapper), 'map'); @@ -90,6 +87,14 @@ public function testMapRawDataMapsFieldsCorrectly() unset($map[Exiftool::SUBJECT]); unset($map[Exiftool::CONTENTIDENTIFIER]); unset($map[Exiftool::CONTENTIDENTIFIER_QUICKTIME]); + unset($map[Exiftool::PROJECTIONTYPE]); + unset($map[Exiftool::USEPANORAMAVIEWER]); + unset($map[Exiftool::FULLPANOWIDTHPIXELS]); + unset($map[Exiftool::FULLPANOHEIGHTPIXELS]); + unset($map[Exiftool::CROPPEDAREALEFTPIXELS]); + unset($map[Exiftool::CROPPEDAREATOPPIXELS]); + unset($map[Exiftool::CROPPEDAREAIMAGEWIDTHPIXELS]); + unset($map[Exiftool::CROPPEDAREAIMAGEHEIGHTPIXELS]); // create raw data $keys = array_keys($map); @@ -107,9 +112,7 @@ public function testMapRawDataMapsFieldsCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsAperture() { $rawData = array( @@ -121,9 +124,7 @@ public function testMapRawDataCorrectlyFormatsAperture() $this->assertEquals('f/0.1', reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsFocusDistance() { $rawData = array( @@ -135,9 +136,7 @@ public function testMapRawDataCorrectlyFormatsFocusDistance() $this->assertEquals('50m', reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDate() { $rawData = array( @@ -154,9 +153,7 @@ public function testMapRawDataCorrectlyFormatsCreationDate() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() { $data = array( @@ -198,9 +195,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone2() { $rawData = array( @@ -226,9 +221,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone2() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectCreationDate() { $rawData = array( @@ -240,9 +233,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectCreationDate() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectCreationDate2() { $rawData = array( @@ -254,9 +245,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectCreationDate2() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectTimeZone() { $rawData = array( @@ -274,9 +263,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectTimeZone() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsExposureTime() { $rawData = array( @@ -295,9 +282,7 @@ public function testMapRawDataCorrectlyFormatsExposureTime() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsFocalLength() { $rawData = array( @@ -309,9 +294,7 @@ public function testMapRawDataCorrectlyFormatsFocalLength() $this->assertEquals(15, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsGPSData() { $this->mapper->setNumeric(false); @@ -333,9 +316,7 @@ public function testMapRawDataCorrectlyFormatsGPSData() $this->assertEquals($expected_lon, $result['longitude']); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataIncorrectlyFormatedGPSData() { $this->mapper->setNumeric(false); @@ -351,9 +332,7 @@ public function testMapRawDataIncorrectlyFormatedGPSData() $this->assertCount(0, $result); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsNumericGPSData() { $result = $this->mapper->mapRawData( @@ -374,9 +353,7 @@ public function testMapRawDataCorrectlyFormatsNumericGPSData() $this->assertEquals($expected_lon, $result['longitude']); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataOnlyLatitude() { $result = $this->mapper->mapRawData( @@ -389,9 +366,7 @@ public function testMapRawDataOnlyLatitude() $this->assertCount(1, $result); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresEmptyGPSData() { $result = $this->mapper->mapRawData( @@ -406,9 +381,7 @@ public function testMapRawDataCorrectlyIgnoresEmptyGPSData() $this->assertEquals(false, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectImageDirection() { $rawData = array( @@ -420,9 +393,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectImageDirection() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectImageDirection() { $rawData = array( @@ -434,9 +405,7 @@ public function testMapRawDataCorrectImageDirection() $this->assertEquals('180.0', reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testSetNumericInProperty() { $reflProperty = new \ReflectionProperty(get_class($this->mapper), 'numeric'); @@ -482,9 +451,7 @@ public function testMapRawDataCorrectlyIgnoresInvalidCreateDate() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyAltitude() { $result = $this->mapper->mapRawData( @@ -497,9 +464,7 @@ public function testMapRawDataCorrectlyAltitude() $this->assertEquals($expected, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyNegativeAltitude() { $result = $this->mapper->mapRawData( @@ -512,9 +477,7 @@ public function testMapRawDataCorrectlyNegativeAltitude() $this->assertEquals($expected, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectAltitude() { $result = $this->mapper->mapRawData( @@ -526,9 +489,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectAltitude() $this->assertEquals(false, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsQuicktimeGPSData() { $result = $this->mapper->mapRawData( @@ -548,9 +509,7 @@ public function testMapRawDataCorrectlyFormatsQuicktimeGPSData() $this->assertEquals($expected_lon, $result['longitude']); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyQuicktimeAltitude() { $result = $this->mapper->mapRawData( @@ -563,9 +522,7 @@ public function testMapRawDataCorrectlyQuicktimeAltitude() $this->assertEquals($expected, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyHeightVideo() { $rawData = array( @@ -607,9 +564,7 @@ public function testMapRawDataCorrectlyHeightVideo() - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyWidthVideo() { $rawData = array( @@ -650,9 +605,7 @@ public function testMapRawDataCorrectlyWidthVideo() } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIsoFormats() { $expected = array( @@ -670,9 +623,7 @@ public function testMapRawDataCorrectlyIsoFormats() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyLensData() { $data = array( @@ -699,9 +650,7 @@ public function testMapRawDataCorrectlyLensData() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyLensData2() { $rawData = array( @@ -716,9 +665,7 @@ public function testMapRawDataCorrectlyLensData2() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywords() { $rawData = array( @@ -733,9 +680,7 @@ public function testMapRawDataCorrectlyKeywords() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywordsAndSubject() { $rawData = array( @@ -750,4 +695,107 @@ public function testMapRawDataCorrectlyKeywordsAndSubject() reset($mapped) ); } + + #[Group('mapper')] + public function testMapRawDataCorrectlyFormatsProjectionType() + { + $mapped = $this->mapper->mapRawData(array( + Exiftool::PROJECTIONTYPE => ' EquiRectangular ', + )); + + $this->assertSame(array(Exif::PROJECTIONTYPE => 'equirectangular'), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresEmptyProjectionType() + { + $mapped = $this->mapper->mapRawData(array( + Exiftool::PROJECTIONTYPE => ' ', + )); + + $this->assertSame(array(), $mapped); + } + + /** + * Data provider for testMapRawDataCorrectlyFormatsUsePanoramaViewer + * + * @return array + */ + public static function providerUsePanoramaViewer() + { + return array( + 'bool true' => array(true, true), + 'bool false' => array(false, false), + 'string True' => array('True', true), + 'string False' => array('False', false), + 'string false' => array('false', false), + 'string TRUE' => array(' TRUE ', true), + 'int 1' => array(1, true), + 'int 0' => array(0, false), + 'string 1' => array('1', true), + 'string 0' => array('0', false), + ); + } + + #[Group('mapper')] + #[DataProvider('providerUsePanoramaViewer')] + public function testMapRawDataCorrectlyFormatsUsePanoramaViewer($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + Exiftool::USEPANORAMAVIEWER => $raw, + )); + + $this->assertSame(array(Exif::USEPANORAMAVIEWER => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidUsePanoramaViewer() + { + foreach (array('abc', '', 2, 'yes') as $raw) { + $mapped = $this->mapper->mapRawData(array( + Exiftool::USEPANORAMAVIEWER => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + /** + * Data provider for the integer GPano crop fields + * + * @return array + */ + public static function providerPanoCropFields() + { + return array( + array(Exiftool::FULLPANOWIDTHPIXELS, Exif::FULLPANOWIDTHPIXELS), + array(Exiftool::FULLPANOHEIGHTPIXELS, Exif::FULLPANOHEIGHTPIXELS), + array(Exiftool::CROPPEDAREALEFTPIXELS, Exif::CROPPEDAREALEFTPIXELS), + array(Exiftool::CROPPEDAREATOPPIXELS, Exif::CROPPEDAREATOPPIXELS), + array(Exiftool::CROPPEDAREAIMAGEWIDTHPIXELS, Exif::CROPPEDAREAIMAGEWIDTHPIXELS), + array(Exiftool::CROPPEDAREAIMAGEHEIGHTPIXELS, Exif::CROPPEDAREAIMAGEHEIGHTPIXELS), + ); + } + + #[Group('mapper')] + #[DataProvider('providerPanoCropFields')] + public function testMapRawDataCorrectlyFormatsPanoCropFields($field, $key) + { + foreach (array(8000, '8000', ' 8000 ') as $raw) { + $mapped = $this->mapper->mapRawData(array($field => $raw)); + + $this->assertSame(array($key => 8000), $mapped, 'value: ' . var_export($raw, true)); + } + } + + #[Group('mapper')] + #[DataProvider('providerPanoCropFields')] + public function testMapRawDataIgnoresNonNumericPanoCropFields($field, $key) + { + foreach (array('abc', '', '8000px') as $raw) { + $mapped = $this->mapper->mapRawData(array($field => $raw)); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } } diff --git a/tests/PHPExif/Mapper/FFprobeMapperTest.php b/tests/PHPExif/Mapper/FFprobeMapperTest.php index 8e240205..32eaea62 100644 --- a/tests/PHPExif/Mapper/FFprobeMapperTest.php +++ b/tests/PHPExif/Mapper/FFprobeMapperTest.php @@ -3,6 +3,7 @@ use FFMpeg\FFProbe as FFMpegFFProbe; use PHPExif\Contracts\MapperInterface; use PHPExif\Mapper\FFprobe; +use PHPUnit\Framework\Attributes\Group; class FFprobeMapperTest extends \PHPUnit\Framework\TestCase { @@ -13,17 +14,13 @@ public function setUp(): void $this->mapper = new FFprobe(); } - /** - * @group mapper - */ + #[Group('mapper')] public function testClassImplementsCorrectInterface() { $this->assertInstanceOf(MapperInterface::class, $this->mapper); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataIgnoresFieldIfItDoesntExist() { $rawData = array('foo' => 'bar'); @@ -32,9 +29,7 @@ public function testMapRawDataIgnoresFieldIfItDoesntExist() $this->assertCount(0, $mapped); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataMapsFieldsCorrectly() { $reflProp = new \ReflectionProperty(get_class($this->mapper), 'map'); @@ -75,9 +70,7 @@ public function testMapRawDataMapsFieldsCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsDateTimeOriginal() { $rawData = array( @@ -95,9 +88,7 @@ public function testMapRawDataCorrectlyFormatsDateTimeOriginal() } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateQuicktime() { $rawData = array( @@ -123,9 +114,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateQuicktime() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() { $rawData = array( @@ -150,9 +139,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal() { $rawData = array( @@ -164,9 +151,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal2() { $rawData = array( @@ -178,9 +163,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal2() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsQuickTimeGPSData() { $expected = array( @@ -201,9 +184,7 @@ public function testMapRawDataCorrectlyFormatsQuickTimeGPSData() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyRotatesDimensions() { $expected = array( @@ -222,9 +203,7 @@ public function testMapRawDataCorrectlyRotatesDimensions() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsGPSData() { $expected = array( @@ -245,9 +224,7 @@ public function testMapRawDataCorrectlyFormatsGPSData() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFramerate() { $expected = array( @@ -300,9 +277,7 @@ public function testMapRawDataCorrectlyIgnoresInvalidCreateDate() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testNormalizeComponentCorrectly() { $reflMethod = new \ReflectionMethod(FFprobe::class, 'normalizeComponent'); @@ -326,9 +301,7 @@ public function testNormalizeComponentCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataMatchesFieldsWithoutCaseSensibilityOnFirstLetter() { $rawData = array( @@ -346,9 +319,7 @@ public function testMapRawDataMatchesFieldsWithoutCaseSensibilityOnFirstLetter() $this->assertEquals($expected, $keys); } - /** - * @group mapper - */ + #[Group('mapper')] public function testreadISO6709() { $reflMethod = new \ReflectionMethod(FFprobe::class, 'readISO6709'); @@ -407,9 +378,7 @@ public function testreadISO6709() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testconvertDMStoDecimal() { @@ -479,10 +448,7 @@ public function testconvertDMStoDecimal() } } - /** - * @group mapper - * @covers \PHPExif\Mapper\FFprobe::mapRawData - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywords() { $rawData = array( @@ -497,10 +463,7 @@ public function testMapRawDataCorrectlyKeywords() ); } - /** - * @group mapper - * @covers \PHPExif\Mapper\FFprobe::mapRawData - */ + #[Group('mapper')] public function testMapRawDataCorrectlySplitKeywords() { $rawData = array( @@ -515,10 +478,7 @@ public function testMapRawDataCorrectlySplitKeywords() ); } - /** - * @group mapper - * @covers \PHPExif\Mapper\FFprobe::mapRawData - */ + #[Group('mapper')] public function testMapRawDataCorrectlyArrayKeywords() { $rawData = array( diff --git a/tests/PHPExif/Mapper/ImageMagickMapperTest.php b/tests/PHPExif/Mapper/ImageMagickMapperTest.php index 4cbb8f7d..01a40cfc 100644 --- a/tests/PHPExif/Mapper/ImageMagickMapperTest.php +++ b/tests/PHPExif/Mapper/ImageMagickMapperTest.php @@ -1,7 +1,10 @@ mapper = new ImageMagick(); } - /** - * @group mapper - */ + #[Group('mapper')] public function testClassImplementsCorrectInterface() { $this->assertInstanceOf(MapperInterface::class, $this->mapper); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataIgnoresFieldIfItDoesntExist() { $rawData = array('foo' => 'bar'); @@ -31,9 +30,7 @@ public function testMapRawDataIgnoresFieldIfItDoesntExist() $this->assertCount(0, $mapped); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataMapsFieldsCorrectly() { $reflProp = new \ReflectionProperty(get_class($this->mapper), 'map'); @@ -53,6 +50,14 @@ public function testMapRawDataMapsFieldsCorrectly() unset($map[ImageMagick::IMAGEHEIGHT_PNG]); unset($map[ImageMagick::IMAGEWIDTH_PNG]); unset($map[ImageMagick::COPYRIGHT_IPTC]); + unset($map[ImageMagick::PROJECTIONTYPE]); + unset($map[ImageMagick::USEPANORAMAVIEWER]); + unset($map[ImageMagick::FULLPANOWIDTHPIXELS]); + unset($map[ImageMagick::FULLPANOHEIGHTPIXELS]); + unset($map[ImageMagick::CROPPEDAREALEFTPIXELS]); + unset($map[ImageMagick::CROPPEDAREATOPPIXELS]); + unset($map[ImageMagick::CROPPEDAREAIMAGEWIDTHPIXELS]); + unset($map[ImageMagick::CROPPEDAREAIMAGEHEIGHTPIXELS]); // create raw data $keys = array_unique(array_keys($map)); @@ -69,9 +74,7 @@ public function testMapRawDataMapsFieldsCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsAperture() { $rawData = array( @@ -83,9 +86,7 @@ public function testMapRawDataCorrectlyFormatsAperture() $this->assertEquals('f/1.7', reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsDateTimeOriginal() { $rawData = array( @@ -102,9 +103,7 @@ public function testMapRawDataCorrectlyFormatsDateTimeOriginal() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() { $data = array( @@ -146,9 +145,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone2() { $rawData = array( @@ -174,9 +171,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone2() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal() { $rawData = array( @@ -188,9 +183,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectTimeZone() { $rawData = array( @@ -208,9 +201,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectTimeZone() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsExposureTime() { $rawData = array( @@ -229,9 +220,7 @@ public function testMapRawDataCorrectlyFormatsExposureTime() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsFocalLength() { $rawData = array( @@ -243,9 +232,7 @@ public function testMapRawDataCorrectlyFormatsFocalLength() $this->assertEquals(15, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsGPSData() { $result = $this->mapper->mapRawData( @@ -265,9 +252,7 @@ public function testMapRawDataCorrectlyFormatsGPSData() $this->assertEquals($expected_lon, $result['longitude']); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataIncorrectlyFormatedGPSData() { $result = $this->mapper->mapRawData( @@ -281,9 +266,7 @@ public function testMapRawDataIncorrectlyFormatedGPSData() $this->assertCount(0, $result); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsNumericGPSData() { $result = $this->mapper->mapRawData( @@ -304,9 +287,7 @@ public function testMapRawDataCorrectlyFormatsNumericGPSData() $this->assertEquals($expected_lon, $result['longitude']); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataOnlyLatitude() { $result = $this->mapper->mapRawData( @@ -319,9 +300,7 @@ public function testMapRawDataOnlyLatitude() $this->assertCount(1, $result); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresEmptyGPSData() { $result = $this->mapper->mapRawData( @@ -372,9 +351,7 @@ public function testMapRawDataCorrectlyIgnoresInvalidCreateDate() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyAltitude() { $result = $this->mapper->mapRawData( @@ -387,9 +364,7 @@ public function testMapRawDataCorrectlyAltitude() $this->assertEquals($expected, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyNegativeAltitude() { $result = $this->mapper->mapRawData( @@ -402,9 +377,7 @@ public function testMapRawDataCorrectlyNegativeAltitude() $this->assertEquals($expected, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectAltitude() { $result = $this->mapper->mapRawData( @@ -417,9 +390,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectAltitude() } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIsoFormats() { $expected = array( @@ -440,9 +411,7 @@ public function testMapRawDataCorrectlyIsoFormats() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyHeightPNG() { @@ -461,9 +430,7 @@ public function testMapRawDataCorrectlyHeightPNG() - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyWidthPNG() { @@ -480,9 +447,7 @@ public function testMapRawDataCorrectlyWidthPNG() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testNormalizeComponentCorrectly() { $reflMethod = new \ReflectionMethod(ImageMagick::class, 'normalizeComponent'); @@ -506,9 +471,7 @@ public function testNormalizeComponentCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywords() { $rawData = array( @@ -523,9 +486,7 @@ public function testMapRawDataCorrectlyKeywords() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywordsAndSubject() { $rawData = array( @@ -540,9 +501,7 @@ public function testMapRawDataCorrectlyKeywordsAndSubject() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsXResolution() { $rawData = array( @@ -554,9 +513,7 @@ public function testMapRawDataCorrectlyFormatsXResolution() $this->assertEquals(1500, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsYResolution() { $rawData = array( @@ -567,4 +524,103 @@ public function testMapRawDataCorrectlyFormatsYResolution() $this->assertEquals(1500, reset($mapped)); } + + #[Group('mapper')] + public function testMapRawDataCorrectlyFormatsProjectionType() + { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::PROJECTIONTYPE => ' EquiRectangular ', + )); + + $this->assertSame(array(Exif::PROJECTIONTYPE => 'equirectangular'), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresEmptyProjectionType() + { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::PROJECTIONTYPE => ' ', + )); + + $this->assertSame(array(), $mapped); + } + + /** + * Data provider for testMapRawDataCorrectlyFormatsUsePanoramaViewer + * + * @return array + */ + public static function providerUsePanoramaViewer() + { + return array( + 'string True' => array('True', true), + 'string False' => array('False', false), + 'string false' => array('false', false), + 'string TRUE' => array(' TRUE ', true), + 'string 1' => array('1', true), + 'string 0' => array('0', false), + ); + } + + #[Group('mapper')] + #[DataProvider('providerUsePanoramaViewer')] + public function testMapRawDataCorrectlyFormatsUsePanoramaViewer($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::USEPANORAMAVIEWER => $raw, + )); + + $this->assertSame(array(Exif::USEPANORAMAVIEWER => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidUsePanoramaViewer() + { + foreach (array('abc', '', '2', 'yes') as $raw) { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::USEPANORAMAVIEWER => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + /** + * Data provider for the integer GPano crop fields + * + * @return array + */ + public static function providerPanoCropFields() + { + return array( + array(ImageMagick::FULLPANOWIDTHPIXELS, Exif::FULLPANOWIDTHPIXELS), + array(ImageMagick::FULLPANOHEIGHTPIXELS, Exif::FULLPANOHEIGHTPIXELS), + array(ImageMagick::CROPPEDAREALEFTPIXELS, Exif::CROPPEDAREALEFTPIXELS), + array(ImageMagick::CROPPEDAREATOPPIXELS, Exif::CROPPEDAREATOPPIXELS), + array(ImageMagick::CROPPEDAREAIMAGEWIDTHPIXELS, Exif::CROPPEDAREAIMAGEWIDTHPIXELS), + array(ImageMagick::CROPPEDAREAIMAGEHEIGHTPIXELS, Exif::CROPPEDAREAIMAGEHEIGHTPIXELS), + ); + } + + #[Group('mapper')] + #[DataProvider('providerPanoCropFields')] + public function testMapRawDataCorrectlyFormatsPanoCropFields($field, $key) + { + foreach (array('8000', ' 8000 ') as $raw) { + $mapped = $this->mapper->mapRawData(array($field => $raw)); + + $this->assertSame(array($key => 8000), $mapped, 'value: ' . var_export($raw, true)); + } + } + + #[Group('mapper')] + #[DataProvider('providerPanoCropFields')] + public function testMapRawDataIgnoresNonNumericPanoCropFields($field, $key) + { + foreach (array('abc', '', '8000px') as $raw) { + $mapped = $this->mapper->mapRawData(array($field => $raw)); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } } diff --git a/tests/PHPExif/Mapper/NativeMapperTest.php b/tests/PHPExif/Mapper/NativeMapperTest.php index ceffd7d0..287e7289 100644 --- a/tests/PHPExif/Mapper/NativeMapperTest.php +++ b/tests/PHPExif/Mapper/NativeMapperTest.php @@ -2,6 +2,7 @@ use PHPExif\Contracts\MapperInterface; use PHPExif\Mapper\Native; +use PHPUnit\Framework\Attributes\Group; class NativeMapperTest extends \PHPUnit\Framework\TestCase { @@ -12,17 +13,13 @@ public function setUp(): void $this->mapper = new Native(); } - /** - * @group mapper - */ + #[Group('mapper')] public function testClassImplementsCorrectInterface() { $this->assertInstanceOf(MapperInterface::class, $this->mapper); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataIgnoresFieldIfItDoesntExist() { $rawData = array('foo' => 'bar'); @@ -31,9 +28,7 @@ public function testMapRawDataIgnoresFieldIfItDoesntExist() $this->assertCount(0, $mapped); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataMapsFieldsCorrectly() { $reflProp = new \ReflectionProperty(get_class($this->mapper), 'map'); @@ -72,9 +67,7 @@ public function testMapRawDataMapsFieldsCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsDateTimeOriginal() { $rawData = array( @@ -92,9 +85,7 @@ public function testMapRawDataCorrectlyFormatsDateTimeOriginal() } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() { $rawData = array( @@ -119,9 +110,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone2() { $rawData = array( @@ -147,9 +136,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone2() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone3() { $rawData = array( @@ -175,9 +162,7 @@ public function testMapRawDataCorrectlyFormatsCreationDateWithTimeZone3() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal() { $rawData = array( @@ -189,9 +174,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectDateTimeOriginal() $this->assertEquals(false, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectTimeZone() { $rawData = array( @@ -209,9 +192,7 @@ public function testMapRawDataCorrectlyIgnoresIncorrectTimeZone() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsExposureTime() { $rawData = array( @@ -230,9 +211,7 @@ public function testMapRawDataCorrectlyFormatsExposureTime() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsFocalLength() { $rawData = array( @@ -244,9 +223,7 @@ public function testMapRawDataCorrectlyFormatsFocalLength() $this->assertEquals(6, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsFocalLengthDivisionByZero() { $rawData = array( @@ -258,9 +235,7 @@ public function testMapRawDataCorrectlyFormatsFocalLengthDivisionByZero() $this->assertEquals(0, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsXResolution() { $rawData = array( @@ -272,9 +247,7 @@ public function testMapRawDataCorrectlyFormatsXResolution() $this->assertEquals(1500, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsYResolution() { $rawData = array( @@ -286,9 +259,7 @@ public function testMapRawDataCorrectlyFormatsYResolution() $this->assertEquals(1500, reset($mapped)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataFlattensRawDataWithSections() { $rawData = array( @@ -308,9 +279,7 @@ public function testMapRawDataFlattensRawDataWithSections() $this->assertEquals($expected, $keys); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataMatchesFieldsWithoutCaseSensibilityOnFirstLetter() { $rawData = array( @@ -328,9 +297,7 @@ public function testMapRawDataMatchesFieldsWithoutCaseSensibilityOnFirstLetter() $this->assertEquals($expected, $keys); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsGPSData() { $expected = array( @@ -360,9 +327,7 @@ public function testMapRawDataCorrectlyFormatsGPSData() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresEmptyGPSData() { $result = $this->mapper->mapRawData( @@ -377,9 +342,7 @@ public function testMapRawDataCorrectlyIgnoresEmptyGPSData() $this->assertEquals(false, reset($result)); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyFormatsAltitudeData() { $expected = array( @@ -399,9 +362,7 @@ public function testMapRawDataCorrectlyFormatsAltitudeData() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIgnoresIncorrectAltitude() { $result = $this->mapper->mapRawData( @@ -448,9 +409,7 @@ public function testMapRawDataCorrectlyIgnoresInvalidCreateDate() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testNormalizeComponentCorrectly() { $reflMethod = new \ReflectionMethod(Native::class, 'normalizeComponent'); @@ -473,9 +432,7 @@ public function testNormalizeComponentCorrectly() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyIsoFormats() { $expected = array( @@ -496,9 +453,7 @@ public function testMapRawDataCorrectlyIsoFormats() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyLensData() { $data = array( @@ -530,9 +485,7 @@ public function testMapRawDataCorrectlyLensData() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyLensData2() { $data = array( @@ -554,9 +507,7 @@ public function testMapRawDataCorrectlyLensData2() } } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywords() { $rawData = array( @@ -571,9 +522,7 @@ public function testMapRawDataCorrectlyKeywords() ); } - /** - * @group mapper - */ + #[Group('mapper')] public function testMapRawDataCorrectlyKeywordsAndSubject() { $rawData = array( diff --git a/tests/PHPExif/Reader/ReaderTest.php b/tests/PHPExif/Reader/ReaderTest.php index d000f819..17ccd846 100644 --- a/tests/PHPExif/Reader/ReaderTest.php +++ b/tests/PHPExif/Reader/ReaderTest.php @@ -7,16 +7,15 @@ use PHPExif\Contracts\AdapterInterface; use PHPExif\Exif; use PHPExif\Reader\Reader; +use PHPUnit\Framework\Attributes\Group; class ReaderTest extends \PHPUnit\Framework\TestCase { - /** - * @group reader - */ + #[Group('reader')] public function testConstructorWithAdapter() { /** @var AdapterInterface $mock */ - $mock = $this->getMockBuilder(AdapterInterface::class)->getMockForAbstractClass(); + $mock = $this->createStub(AdapterInterface::class); $reflProperty = new \ReflectionProperty(Reader::class, 'adapter'); $reader = new Reader($mock); @@ -24,29 +23,23 @@ public function testConstructorWithAdapter() $this->assertSame($mock, $reflProperty->getValue($reader)); } - /** - * @group reader - */ + #[Group('reader')] public function testGetExifPassedToAdapter() { - $adapter = $this->getMockBuilder(AdapterInterface::class)->getMockForAbstractClass(); + $adapter = $this->createMock(AdapterInterface::class); $adapter->expects($this->once())->method('getExifFromFile'); $reader = new Reader($adapter); $reader->read('/tmp/foo.bar'); } - /** - * @group reader - */ + #[Group('reader')] public function testFactoryThrowsException() { $this->expectException('TypeError'); Reader::factory('foo'); } - /** - * @group reader - */ + #[Group('reader')] public function testFactoryReturnsCorrectType() { $reader = Reader::factory(\PHPExif\Enum\ReaderType::NATIVE); @@ -54,9 +47,7 @@ public function testFactoryReturnsCorrectType() $this->assertInstanceOf(Reader::class, $reader); } - /** - * @group reader - */ + #[Group('reader')] public function testFactoryAdapterTypeNative() { $reader = Reader::factory(\PHPExif\Enum\ReaderType::NATIVE); @@ -67,9 +58,7 @@ public function testFactoryAdapterTypeNative() $this->assertInstanceOf(Native::class, $adapter); } - /** - * @group reader - */ + #[Group('reader')] public function testFactoryAdapterTypeExiftool() { $reader = Reader::factory(\PHPExif\Enum\ReaderType::EXIFTOOL); @@ -80,9 +69,7 @@ public function testFactoryAdapterTypeExiftool() $this->assertInstanceOf(Exiftool::class, $adapter); } - /** - * @group reader - */ + #[Group('reader')] public function testFactoryAdapterTypeFFprobe() { $reader = Reader::factory(\PHPExif\Enum\ReaderType::FFPROBE); @@ -94,9 +81,7 @@ public function testFactoryAdapterTypeFFprobe() } - /** - * @group reader - */ + #[Group('reader')] public function testFactoryAdapterTypeImageMagick() { $reader = Reader::factory(\PHPExif\Enum\ReaderType::IMAGICK); diff --git a/tests/files/gpano.jpg b/tests/files/gpano.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f47b81d1b9532aa7d5697cbb51facbaa7221ad48 GIT binary patch literal 203275 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

(N%}~ zOlXB3cunVb=*r|r=>D4aZ1Ttx%43;j7&Z`qMyb7gH%peZbB5<4RGchkKe zT(p(VN7lh+#~IGLKpIjENWxJgSMr$ZhYuZs-*fevEbFS^94n4l(^uYshhSUM})3)xHa6D*qS-lTmY z#!U~RtGX2KD?ff1|9&U@+TCkBue6sMkL*Eu_Q zH0#OJyd8XlvRIN{NNCL@DNyKD;@GaQ9dnsS+}Dv?vU&?)1j`Oj?E6G4N;MWxVy}-O z*N<@z)*4xMVf;m#O0KM8KV<1@TJw7IL4xj{9k z`yM1ByN_eYw%UgBUkB-lYjOuP2RC%AvyY*x6eau1lO4lvBE?>!u7G+=NSJPQ0#$75 zcN@%D9bSz63YR-lesc_gbr>_~WLT7NH%Rs`~mb(oS6qd+&tY z5}{SFsE-W&hVeiC#x!xwDxf)UNR>meKQl6%el|kiS(WB6@FME{$6pHFSnHS*HNN*)|8S|Wjw=@H~Y~wF~b1c$diOpMZlyUz}S7iehaVJ%DjYy7Aua;kb z4b9K4wczK*|)w}>4WP8ybsDj$_#gr9q$!hVmMR^2_TLvhF>cCd$fgf0bRV&XPWDOKr-LkYDq-)1!IOpSFe^Y5HM>s_q)r-0} zxohXwJMW@{`MW6R=Zog)8}>!6#}M_eW2nk6?m>=SBS%H~8cB?)^ch;(Oybm9)si|l zgUG{2&L3Ca9)r7XC|d!fG@j7U92%-(3~9p)?5rHh@Y2yK+h}DhjLN&!`F>4v#HwIe4paCO*gqP@d0puz$h-T^$qKoeG$W_J zuwyX%_13f1XyI@zTxV5!xkJhPpwc4Z$%%gzG^ywtC4S9!Q|L-PXqra+jh$EG@Hn5FRqcf_<04t z7CPkq@-fuP7J9V5Dn~EojEKEn1J;JoP?o?^h+nDTX0djSh{%;Bsoa4D)J{Ay2bikb zrC`!-c%92{9z~`3b(bDPy>T6jZ7O+ADZXCoa`ZG_pQyoo4`(H!T~a6gcyXE=?_b6r ziYvI7adfG)qmaP|3;V-Pd9v6uY+;BIA9#)5fBrD|TaDc)k&$c9fPlU4I1S~4OmK6e z@I!0a*pCXAI-)mzOD5c0$Iz{3D8%7o7otaP-Y-AU`y`dGEat)9Vd`m7Vs!tmCrVmp z^5^vb$b*mY`ZoE9Dw{;rY3@~cYVNAot-BAahMyzdLJk&$ z7RM6XmHR8OkZC@*@=rUL&)CRAbhq$Br=-#%f1GvQO>KrfTL?2HuGxsbnU_6Jhf138 zin)y&nWaAwZiH_Zl(=?1r^%_-()`hP7MKM6-=7$GV< z4`C1w^^3ccjC&R*?}{QNP8%zwkUIPA=or-;mm=5U+VPIbiRj1`lQz+9FQO-4xdXGa zl82IdzrV@6!CQ8Nr1;yVnAC0MJ9+sN#RV>ovE~KIx@@Re#m$6Q zI=yV*U$?35FCAguRh{CFY`nLnv+_*;LB+CU^U1w6-sHr*BUNjEuh5Z(l4Md_Eb&y-DsqM(2 zy1RFH@$QxQ6f4x7&3kM;xnXm?e}9;6Y)RA`oa9G>RpWs?Lf9+zKDD5Z`f?0q41p{0 z_?O(PAba=7?+r4}U3;W2WiDS~v#TL-5bPUP!anXJigBfAHpGILCtHToRW0HTWAam1 zL&WC%W-FAgj`!7Yy7PHH&67MM@@}m$2BM4&2na3kCMi3kTv}shiHj-Jx?Oy8%f=!| zU3p8OyoFI&L7!Sc``1r=Bg_`C*K8c%tBbnnv^LA>yWOK~8C!;9Rh8O)z|cbPer{xE z)@J@}_liz==aqH#5gVtlkgqpXymh7G-&y3TwDRq+sirUUyp47ld=Z)K{c3-3!@|`r z>)OTUce2SZ2!on>ZfH+RCvvEGbu~HoC``zbOEbySG<17y3C%qc&CZe#E~a_%hon%}`j&mWK4gW8%d{L> z;!DPuZbPvrGFMtD&C!>!OuU$B}YjFz&iWZ7H1S#%L zk>c)dg+L1}r4YQh6n7~aDAE@90>!Nacc)nT4Zr)|b?>*{8sL$jP*3~AN78@08^)pRs72Mqy903%Mxi&B>2f-e4q-l zu>3&a<8vW?Lx59_$dzTOe>ocKfDcJFO4-kLZdgOP4g?>?O!Bw$r?|##ibfNsv(;6j zl7$D+`6S9S#v=Te=Lhe)9mpr0o~sT=v|OK@?++GF6i)SX76p)N?tcOX8y=fxnA<5m z@ZZ+piy86pcC>4E@m71t^)KK$U+HW&OuUik12hT~!0^EQwadtV+=Rm_-7B?=THa4N z&eOM}#1Eux90v{p^vLTqNNTXhvj*CP+jqcRcC3xBK1#iQP)xCxz1dW`Akm0 z^WHB_nJ?Xn_`fioNc?U;y9+1lvW5Z|*gOjh! zK6Xg1&lH5;r1hJZf>V8H8Qg>uz5Ez9?P5=O_iol&@}&zJc`nM?)cjuQQ?2WZ!8G$x z9u_Xe(tKh@3fjniCi8pkBtcJwc7G4*l(=D7R^4qnG$ra&u+gC$o9+AfM8bcuv?q_8 zM_N{R+ITCHp)D>n9tkRMXF(S-6nnMNp9iypCp&m-VbX>}|3D}4`MX|Rp-gB%Z&)8! zUvUfK$}CDYp_St%Dyk9iA-!5YqT`vFv$1>LIxxWeg{i*kBE9jhsojZHLLg@-+?(&= zIQSqkNs-hftJ&!x&ylHF=bI>Z^$2i|_fXMNRkKK}&2Rub%g>71 zH)(Q(B}Y>}F^!LXWPZ4{6PzgpL5q_3dJn*gh#@P*(M)F z+}uwgXx?q*yGP>hUfuS5Vp{y>POo`D>@8vF>eVjxomua`Pih~p!IWB0+MSr;8$iWP zHhz?x+vp#?iiIM6Pv^BcOkc#JjfoZaT5G2)d?6^+W-JJ&gs~3hCAeD2JF}E^yY(;{~E9?etqK4 z(%35EiDM}I5qxxX*At9rl6}an_HP&zOgh})Izzc+NLgs8Pc|EvrPpAl;}B)JCA^4J zWI8l^@>w$ZSXY<&r-tk4NOOsIpLwfg;ZpD|?g6*uom87byZ_4HKIg?YB|nvAx6ZCF z-iaC7cIoVwY~&d~blPLA(VL5KlIwR66SL1}2Hp22dvr?tc?fwi6?v74)tiMQtNoS+ zGhfE2;~%iS)75Vk!eE<**^R7QjsF9Iy~2ckEkK7Mw}1bE<}2+^lCGt2V`pq=94m-Z zv>8irL4j3^*F8$RGGLLt_|7Z&W8)tk3iW;0#8b|Z03mIfY3-g_e4x8@x#$($tLZW> zg_62Kvwa^0xX5t812eU}-zSlt$PfMmy*o#o7%1}6_yH)=q>P`x$0945-C8=iWWA7nqg}koejxvYZ2A zifXvqpB(>DQc-#|cF~G1>rMBlDD4Vz8C*;defdRf^q5>d7WlnOGVJK;6_fsgtUst( z+EREUNxHPycS_}6(L40hv6pB4Qm5>hEiMT8G#4rdA<_FO(X{u&ZV6TRPwbnY9)B~Z z5>0OpxKjMMDnA9CQZAi+A48c7@Vi%ZY;A+XT+)A?Rn}EnzJXg}@9u=$+E?(x(r!LB z%VJy{xt$BE#HP_It$e>iG#QD^c3JbgOFN{K5mZhMkC)c|H8}fev0rshklx_ZPZDcu}D!db}2_TrlhOs@au}-d(6>JB~ze+2n@eWal3OJ?l>Fx9^c8^l*<~lM%6O{AEeyWKTtRHg2bG7 z=|>1XHs|hm7iLO{cK!xo?(g~tbU6i{Qv6n_;H?fUd4h*byl|ogC2)*>NBYe6mwzDa zTRpDu9V#b2b#y?ziaJ&QAKbDaoRW-2hWi;WMNW(i6(IP16#eQsQX8s8|DsOw&CuRl00?Z~c>d-_rO)ZO@&NcMKZisMyLoLDt;R&slQP4=VyDnE{#GM}o7OgD{h zZeyXImA%*5UUX6$on<2xD{oV^qU?*lB_W7hB|5oDfzS56k}iq?TVkSq4Kv8X45vCZ zQ90FyB_h5fFKn(d*kB{AUP76SoS9as471%_XlOo7xMW9m94$Gy7ed}|qXwgQ$(ZTC zjsHt|QMJ-bS6(c|m6Jsk06x7Wl-hS**$NrnDO`}_iU?o!41yH94P|Ovuw_&e_8t9c z+$r=Ycy8L9q{X#+Sy^Y+E9kr`7}EAU2H?UjcRT!ewN^HHy!KV%g9*_4J6N%*K~xM) zj0_hj>}WHsp?*J1yO@i0mz2icy?gGaTz-qbr%^>G)8=#O{8hMSs5iGjoBJMLW80p>Bd>(k#niWtlDuH62%Y!iBa!i?noW~Fl&L@28A)O;%murfDfa9< zRt9=fwq5YS8~I3~lxA-CfM@SP-|yoT&4R%LvnUga7K;~xxz4bBq+&YG_6v^m%&;{p8QWslTvM$ z?cvtrB;TfUvg6%9&?>+};|Ao0Fau3N(0hOI*(eZs#mUxgtJ{YYO?O{`b03la+(w}? zt1^#uWkrsRbh8foUf@ANfBKN;SU-9bE<1j77NOOG1<7?W9#mMaOw%QB^6_4Mph17j z^-3|s#v|tIiH(&;| zDp%{}3U+RJdn$_b9>ZnkQ*exrzPKW4GX;`EES%Y{C;*nj|E}BsLszBVZ9JHPDJs@fbZv~ ze0`G5;{)q_+ssEf%;~Kpg^6Wy=o^dug}F5E=|9kbACbN8(nXRBSm(2{n_ADJsgzgd zx@nda%xrahYx!lGx@}9`(iS=B@OsqS;v{M1_K`{QKYO{of%22*sTI(e=PoLO|#d%RMWVNZ09vf0pnnE~Z{KNf4-Q?g$vSxQ3xKsXw+ z_h+yUuv%NlvNYERkia&h?^@ymhbjj*im>yHVe#_>Q_PRe%?A#kE1?*ZOo2pm#mgq@ z=fG)zcWuvoJ4COW!e#-;UuvP{D{s5t#eB)umt!qfkDJ^@W6*skk1z3rzoJtpH+3*Ocs9LdwhgW9}d`Q5iM)CS{t>qOy)L zLw4exfO*2}-C?$J4~tAwZj*Ivx+;|xv|0m9xPMnGi%79Ra!f8Cl9$Nh2cwC9kk^aRQ(L8-=)Ud$fiq8=E#NM)L092e?>4O)*ffyDC#rxE|YQyhl0Eas7 zGTgO!Z47*sE_BDbo#Oz2_AomTKl9Ge0jCiG-BBzEA(Y6G=6Yg4-K>M0y$~9w|J5+J z#`F)A7_*IBgtFF(O1VrrQ13|->;?f|<#9AU^(s}?o)Kj!^Sl&3OCOUag1R!ljXjA@ z{o}eu*EFj`OXYK5bc=a6Cqm*wm{ymkgl<$#Mnint{J>9)X_}6*Z}v{HWu`vvkdWDv ziZCY8-?rZ&02dJKJ$)|sn zZPeNn0^eSEJm9!Y!Ui@&vQvGL^pI1DCP2*g55z1#mlBG;>eu)q8AgnS*0Z%t`ZflR7Hh~iX-tS^>H`})wMc*MUU@oNKDzV8+}*y z)0HAy{8TCBOQA-?NHy>Eeygj%tqjSIo97D>JqKlClnK-&UxP%Jaw`W zc_#fyGh3!pOiNVORNWTqmjk;BY*Z3Wo|!4B$(;L?{PILeHbLYm^m}6HBs1UCEK<}0 zvGJv4q^;sjR)`dRns2JS3*MQAF92h%MwH;u0L`X@E4=7l?`iSfjDWnorWXZJlZ{5` z4Nfm`qS0qn=czgd{NitLmY^LETq$V}RweQhNM62~h&+>RMkk@gop1f_QVz-gKnfFA z-0s1ART_Gq7OlM5@ftPIvEOMFR6qm%7(&!c*C8b+DFeF<>)2=fffsKGt`-P5KUpuUqT z$F41khFWG(X3F6SVtBXzO2K4cxjn;sX^!5&I!ST~OB+YqGmtskC}HocaUtiYG=Gh@ z%>*6pC3TPK$;nug+a=@{r#83-=g7Cmq!8#!pF{Was}OD62X?X#v3?dy5m(EHd0p4= z@s{eq&?Q~k3}eMP9!<|sm&std$XjdP-`xB~L}C)qMy{P9MA_)tGj8uJy3x_ET7En? zFIBV5>Z$3h;k5@@E)sZm(Jv-9ZZL4m=xpE3<*8mE>IbeR^T?+Hp-6e*u4AaY$^lDA z$MkzqIv7Y-4ZNv6$6+ek;>Qfh7!5kSkRUXD6>qn7d|U>Zx;1*irlYIN{{lefrtbzH zFbvYb^A$>^$Pt$b*uci;bu(aKAv}e|cm?yqMUsEP(kg-W7eYG$1TO|r{&*XVd3t(= zI*0HoOw+py@=m^tC~I?K)lx}sE@+C0<(me}?P>O~*0m&R-h@io2sgd_d#W_EmG9`ho5 zJLb5wew2I6RolhqX^J*)alYbAdR8gi$hs+hheE7(HGTJcmLxW$k_4OeqV6&f zd1E};iW33LmnxDd?Lx~=o{iQcUtO04>d?>QA{{P-Uf4TU1z^@S$!1vsB<6cKqD>@( zAq0FMDHMN;5IL_Eu2sp7z7g@AtxsUw0V~39tptE+hT=aha|3D=U|3LC4 zho$x7++*A}+yi~mO-CzWs$bRp4M2b2koyz1`5<>#Rh?z~Y#ha$y53ghKrKYk zo?E!~=dQi0B7XaIvYEiriUeWRvOH39M4EndQSHX z9qb1%5%{+4tiqr3IOplS{}?mYgyttEGOtug5-mDUaieU1x~&!lOPJ=~958}>Fz6nf z))usL#-aeQo++(e{Y}Uzmqk8+3&sTllk3kL0S+{7rT4fEyy`A_I)<_{yZ=C^2VM{7 z_fbxnh}>;;e_BJgKzQ^&P%|XQ`qhpR+XK(k-sur8v+ zN;9SGsKxk_Uoo45yCw<#3^agK`XA1jwPU^2+1*#k%30QIt5l#?Snww7(QIknd9?cg z!i6ibZFo8dfxE5nW5NKE-;TQ(0I?Z5jyqy|{3fP+&}?jGEa_@aQnTHBWO21Xa<+^8`oJY_&a7oF#iBhXZ*$B}FC96nVCKEFjG^6O81jl- zmIVePp@x8-7fqCw4Zx( zU6th~y~(_=7rueGu0#qga_fx6DRVQ3>CEN-M2qKx_O;_~B-OW3eE#};yT&pJaajKn zo>+*Y=#`r~EL&`0vTKq#jIzqfsGv*Lj5Ch5|2o@WiFWC{_F(wW%oqas(DK)C>!X7g zL#^wiEGN6W+Ee;Cwz^+O@PcnsWtB`yzVWnl`J$qi`)0z`F7)39>QPb5va_#?bj92Z zSBwuxa)q_+`jl^H^oNE^ST`BT(VwhtIbRfh60$$7e@PI-+x{d zEMjr35wh&1IZ|k%Ic={~gV?_1mfW>hXb0xYYMe&I<3<%4oSi;WM?aLY$nvepPaQM;^NV&g8 zv{vurC&g3|8#06e`J+Hh?sx5%S(@lsv2t2+gXcXUF_x<;yqwoV%lBQpgFK$h9|K53 zr8pKgSyuY&R!ZNbozC~#k`1ikm_9EGkhCd%-Q;jEJ6>L!B_NdfHaMdFAqm5AQpI>X zz-~WOm@A|?=M_u|H-u)2w{NnlM2P=|5_95TBrCk2%1=zB+)`V?(N;LE>1ot6G>Q~m z6pd&9BV?G5Js;~aq_6ccheT{aa#H?-0^8@jC5xeO;-3uA-?b0tnk4x6(3Ump46KpXO&SZLX$aY~^eCByBjGXdMX9C$OKd7W6_( zeg28~SrEN#t)T>S+>vqX)K=Fo!KQciIye&PgsoMICx<|MOn?8Kb(zu^M+)z`IVuN` zSV{|)RFrSiPd(tu;;0zYklRMtCenSz&kLZh=-Y*C7lNx@feCC@jQz8*G^YRw4KGy5 zxY!nEQK|#yv@1d&frfNF(&Hbf*C0fZuBhJeGl??2TLQ_%d+6TpYQa1^nI4L0&ydvX z>#B_-T|*uPCe?^v?>LS)2daidiAYIZH?(DLXU7i*g_gB!a!o&~*Svem;Yh3tYed;y z;J3mEz$y+pTe_g=r}yz-iDSg|**e@7Orgk#cV10UmlVyxU92CzRoX%m zH(Atz|M|2Iz3<)DEom@~m>X>>kIUJY2B$AaHr@w2rHN0Ml*HDMd2!~S`zB4(k6vR4 zJRNYqxxTDXuB3;V$32fBl-e74iCBTLQx!5ab~r_=>$>G*d@uTbQN-uz_`Mgz%E9Z1 z0;jD{%u`JQu(mL;Ie=1`~#g40FJ%}^2eOqQHA#Ec3QEO z^U)u25cp)`sL1pJXn8^A5WQ;M05iHahMJ4$;YU6S>OGvb-@h}|8g18Q$EKEoV?gH~ zPX?Rk`+{dbFf;*|Fw^uCa0&Tb8Z1%Cm{Dz5~xsVOz zeW6_K@)^y`!>Bl9!o$N8vi+ofqN9A1I~-hPue}yW*d%p^qP*!WxKJL7eEC$|>noXWC_3P~R3Mx-F*G2`aEZBMIu} zoWCaP+z$&np6Yo0!K`zD)VT0TuA#cGsB~u&VWzwuT;!gG)P}V?YBBpJCy;Gwk!<=D zKZzH$`;aB>`(MOK*;Sa`Ia**OhVJvtn|8nMF$hG}@Dvq!E_}{2qs#y9=rs2Mfc>?e zn)NXEc*bQ-T77udDLa(C=C?oe`}a(~2q)~Q$U~0TtDV{7vV6k^PIOh}{c7N?JwL6d z7}l}nHh^syJptldi@3z_w%%_l-^ef&&Xn}VwoF%d{-O>^(Je6Vh4H1K``sEIn8a0O z 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 literal 0 HcmV?d00001 From b4f4452c36c19c0b07e5a3b06a4465b13df203d3 Mon Sep 17 00:00:00 2001 From: ildyria Date: Sat, 3 Oct 2026 22:09:51 +0200 Subject: [PATCH 2/2] feat: expose exposure bias, white balance and colour temperature Map the EXIF exposure bias (ExposureBiasValue / ExposureCompensation) and white balance mode in the Native, Exiftool and ImageMagick mappers. New getters: getExposureBias (EV as float, rounded to 2 decimals so all readers agree) and getWhiteBalance (EXIF code, 0 auto, 1 manual). Unreadable values are skipped. Add getWhiteBalanceTemperature (Kelvin), read by the Exiftool mapper only from maker notes (Canon, Apple, Sony, Fujifilm, Panasonic, Pentax) with Lightroom XMP-crs as fallback, measured values first. Other adapters return false. --- lib/PHPExif/Exif.php | 88 ++++++++++ lib/PHPExif/Mapper/AbstractMapper.php | 47 +++++ lib/PHPExif/Mapper/Exiftool.php | 95 ++++++++++ lib/PHPExif/Mapper/ImageMagick.php | 16 ++ lib/PHPExif/Mapper/Native.php | 16 ++ tests/PHPExif/Adapter/ExiftoolTest.php | 31 ++++ tests/PHPExif/Adapter/ImageMagickTest.php | 31 ++++ tests/PHPExif/Adapter/NativeTest.php | 31 ++++ tests/PHPExif/ExifTest.php | 86 ++++++++- tests/PHPExif/Mapper/ExiftoolMapperTest.php | 166 ++++++++++++++++++ .../PHPExif/Mapper/ImageMagickMapperTest.php | 76 ++++++++ tests/PHPExif/Mapper/NativeMapperTest.php | 80 +++++++++ tests/files/gpano.jpg | Bin 203275 -> 203428 bytes 13 files changed, 762 insertions(+), 1 deletion(-) diff --git a/lib/PHPExif/Exif.php b/lib/PHPExif/Exif.php index 666657f3..37434aea 100644 --- a/lib/PHPExif/Exif.php +++ b/lib/PHPExif/Exif.php @@ -33,6 +33,7 @@ class Exif public const DESCRIPTION = 'description'; public const DURATION = 'duration'; public const EXPOSURE = 'exposure'; + public const EXPOSURE_BIAS = 'exposureBias'; public const FILESIZE = 'FileSize'; public const FILENAME = 'FileName'; public const FOCAL_LENGTH = 'focalLength'; @@ -63,6 +64,8 @@ class Exif public const TITLE = 'title'; public const USEPANORAMAVIEWER = 'UsePanoramaViewer'; public const VERTICAL_RESOLUTION = 'verticalResolution'; + public const WHITE_BALANCE = 'whiteBalance'; + public const WHITE_BALANCE_TEMPERATURE = 'whiteBalanceTemperature'; public const WIDTH = 'width'; @@ -349,6 +352,91 @@ public function setExposure(string $value): Exif return $this; } + /** + * Returns the exposure bias (exposure compensation) in EV, if it exists + * e.g. -0.67 for -2/3 EV + * + * @return float|false + */ + public function getExposureBias(): float|false + { + if (!isset($this->data[self::EXPOSURE_BIAS])) { + return false; + } + + return $this->data[self::EXPOSURE_BIAS]; + } + + /** + * Sets the exposure bias (exposure compensation) in EV + * + * @param float $value + * @return Exif + */ + public function setExposureBias(float $value): Exif + { + $this->data[self::EXPOSURE_BIAS] = $value; + + return $this; + } + + /** + * Returns the EXIF white balance mode, if it exists + * 0 = auto, 1 = manual + * + * @return int|false + */ + public function getWhiteBalance(): int|false + { + if (!isset($this->data[self::WHITE_BALANCE])) { + return false; + } + + return $this->data[self::WHITE_BALANCE]; + } + + /** + * Sets the EXIF white balance mode (0 = auto, 1 = manual) + * + * @param int $value + * @return Exif + */ + public function setWhiteBalance(int $value): Exif + { + $this->data[self::WHITE_BALANCE] = $value; + + return $this; + } + + /** + * Returns the white balance colour temperature in Kelvin, if it exists. + * Only the exiftool adapter provides it, as it comes from the maker notes + * (or Lightroom's XMP-crs data). + * + * @return int|false + */ + public function getWhiteBalanceTemperature(): int|false + { + if (!isset($this->data[self::WHITE_BALANCE_TEMPERATURE])) { + return false; + } + + return $this->data[self::WHITE_BALANCE_TEMPERATURE]; + } + + /** + * Sets the white balance colour temperature in Kelvin + * + * @param int $value + * @return Exif + */ + public function setWhiteBalanceTemperature(int $value): Exif + { + $this->data[self::WHITE_BALANCE_TEMPERATURE] = $value; + + return $this; + } + /** * Returns the Exposure * diff --git a/lib/PHPExif/Mapper/AbstractMapper.php b/lib/PHPExif/Mapper/AbstractMapper.php index 4b40187c..ded11a16 100644 --- a/lib/PHPExif/Mapper/AbstractMapper.php +++ b/lib/PHPExif/Mapper/AbstractMapper.php @@ -71,4 +71,51 @@ protected function normalizeInt(mixed $value): ?int return (int) $value; } + + /** + * Normalize the exposure bias to EV, rounded to 2 decimals. + * Accepts a number or a rational string such as "-2/3". + * Rounding keeps the readers consistent: exiftool -n only + * prints 10 significant digits, e.g. -0.6666666667. + * + * @param mixed $value + * @return float|null null if the value is not a valid number or rational + */ + protected function normalizeExposureBias(mixed $value): ?float + { + if (is_numeric($value)) { + return round((float) $value, 2); + } + if (!is_string($value)) { + return null; + } + + $parts = explode('/', $value, 2); + if (count($parts) !== 2 || !is_numeric($parts[0]) || !is_numeric($parts[1]) || (float) $parts[1] === 0.0) { + return null; + } + + return round((float) $parts[0] / (float) $parts[1], 2); + } + + /** + * Normalize the EXIF white balance mode: 0 = auto, 1 = manual. + * Accepts the numeric code or the exiftool labels "Auto" and "Manual". + * + * @param mixed $value + * @return int|null null if the value is not recognised + */ + protected function normalizeWhiteBalance(mixed $value): ?int + { + if (is_string($value)) { + switch (strtolower($value)) { + case 'auto': + return 0; + case 'manual': + return 1; + } + } + + return $this->normalizeInt($value); + } } diff --git a/lib/PHPExif/Mapper/Exiftool.php b/lib/PHPExif/Mapper/Exiftool.php index 9f97f96a..ead84205 100644 --- a/lib/PHPExif/Mapper/Exiftool.php +++ b/lib/PHPExif/Mapper/Exiftool.php @@ -37,6 +37,7 @@ class Exiftool extends AbstractMapper public const DATETIMEORIGINAL = 'ExifIFD:DateTimeOriginal'; public const CREDIT = 'IPTC:Credit'; public const EXPOSURETIME = 'ExifIFD:ExposureTime'; + public const EXPOSUREBIAS = 'ExifIFD:ExposureCompensation'; public const FILESIZE = 'System:FileSize'; public const FILENAME = 'System:FileName'; public const FOCALLENGTH = 'ExifIFD:FocalLength'; @@ -55,6 +56,7 @@ class Exiftool extends AbstractMapper public const TITLE_XMP = 'XMP-dc:Title'; public const XRESOLUTION = 'IFD0:XResolution'; public const YRESOLUTION = 'IFD0:YResolution'; + public const WHITEBALANCE = 'ExifIFD:WhiteBalance'; public const GPSLATITUDE = 'GPS:GPSLatitude'; public const GPSLONGITUDE = 'GPS:GPSLongitude'; public const GPSALTITUDE = 'GPS:GPSAltitude'; @@ -100,6 +102,20 @@ class Exiftool extends AbstractMapper public const DURATION_WMV = 'ASF:SendDuration'; public const DATETIMEORIGINAL_PNG = 'PNG:CreationTime'; + // White balance colour temperature (Kelvin), from the maker notes or Lightroom. + // Listed in priority order: measured / as-shot values first, user settings last. + public const WHITEBALANCETEMPERATURE_CANON_ASSHOT = 'Canon:ColorTempAsShot'; + public const WHITEBALANCETEMPERATURE_APPLE = 'Apple:ColorTemperature'; + public const WHITEBALANCETEMPERATURE_SONY = 'Sony:ColorTemperature'; + public const WHITEBALANCETEMPERATURE_FUJIFILM = 'FujiFilm:ColorTemperature'; + public const WHITEBALANCETEMPERATURE_PANASONIC = 'Panasonic:ColorTempKelvin'; + public const WHITEBALANCETEMPERATURE_PENTAX = 'Pentax:ColorTemperature'; + public const WHITEBALANCETEMPERATURE_CANON = 'Canon:ColorTemperature'; + public const WHITEBALANCETEMPERATURE_LIGHTROOM = 'XMP-crs:ColorTemperature'; + + public const WHITEBALANCETEMPERATURE_MIN = 1000; + public const WHITEBALANCETEMPERATURE_MAX = 50000; + public const PROJECTIONTYPE = 'XMP-GPano:ProjectionType'; public const USEPANORAMAVIEWER = 'XMP-GPano:UsePanoramaViewer'; public const FULLPANOWIDTHPIXELS = 'XMP-GPano:FullPanoWidthPixels'; @@ -123,6 +139,7 @@ class Exiftool extends AbstractMapper self::DATETIMEORIGINAL => Exif::CREATION_DATE, self::CREDIT => Exif::CREDIT, self::EXPOSURETIME => Exif::EXPOSURE, + self::EXPOSUREBIAS => Exif::EXPOSURE_BIAS, self::FILESIZE => Exif::FILESIZE, self::FILENAME => Exif::FILENAME, self::FOCALLENGTH => Exif::FOCAL_LENGTH, @@ -141,6 +158,15 @@ class Exiftool extends AbstractMapper self::TITLE_XMP => Exif::TITLE, self::YRESOLUTION => Exif::VERTICAL_RESOLUTION, self::IMAGEWIDTH => Exif::WIDTH, + self::WHITEBALANCE => Exif::WHITE_BALANCE, + self::WHITEBALANCETEMPERATURE_CANON_ASSHOT => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_APPLE => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_SONY => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_FUJIFILM => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_PANASONIC => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_PENTAX => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_CANON => Exif::WHITE_BALANCE_TEMPERATURE, + self::WHITEBALANCETEMPERATURE_LIGHTROOM => Exif::WHITE_BALANCE_TEMPERATURE, self::CAPTIONABSTRACT => Exif::CAPTION, self::GPSLATITUDE => Exif::LATITUDE, self::GPSLONGITUDE => Exif::LONGITUDE, @@ -195,6 +221,20 @@ class Exiftool extends AbstractMapper self::CROPPEDAREAIMAGEHEIGHTPIXELS => Exif::CROPPEDAREAIMAGEHEIGHTPIXELS ); + /** + * Tags holding the white balance colour temperature, in priority order + */ + protected array $whiteBalanceTemperatureTags = array( + self::WHITEBALANCETEMPERATURE_CANON_ASSHOT, + self::WHITEBALANCETEMPERATURE_APPLE, + self::WHITEBALANCETEMPERATURE_SONY, + self::WHITEBALANCETEMPERATURE_FUJIFILM, + self::WHITEBALANCETEMPERATURE_PANASONIC, + self::WHITEBALANCETEMPERATURE_PENTAX, + self::WHITEBALANCETEMPERATURE_CANON, + self::WHITEBALANCETEMPERATURE_LIGHTROOM, + ); + protected bool $numeric = true; /** @@ -403,6 +443,35 @@ public function mapRawData(array $data): array $mappedData[Exif::LENS] = $value; } continue 2; + case self::EXPOSUREBIAS: + $value = $this->normalizeExposureBias($value); + if ($value === null) { + continue 2; + } + break; + case self::WHITEBALANCE: + $value = $this->normalizeWhiteBalance($value); + if ($value === null) { + continue 2; + } + break; + case self::WHITEBALANCETEMPERATURE_CANON_ASSHOT: + case self::WHITEBALANCETEMPERATURE_APPLE: + case self::WHITEBALANCETEMPERATURE_SONY: + case self::WHITEBALANCETEMPERATURE_FUJIFILM: + case self::WHITEBALANCETEMPERATURE_PANASONIC: + case self::WHITEBALANCETEMPERATURE_PENTAX: + case self::WHITEBALANCETEMPERATURE_CANON: + case self::WHITEBALANCETEMPERATURE_LIGHTROOM: + // resolved once from all available tags, by priority + if (array_key_exists(Exif::WHITE_BALANCE_TEMPERATURE, $mappedData)) { + continue 2; + } + $value = $this->extractWhiteBalanceTemperature($data); + if ($value === null) { + continue 2; + } + break; case self::PROJECTIONTYPE: if (!is_string($value) || $value === '') { continue 2; @@ -440,6 +509,32 @@ public function mapRawData(array $data): array return $mappedData; } + /** + * Returns the first valid colour temperature (Kelvin) among the known tags, + * in priority order. Values outside a plausible Kelvin range are skipped: + * this drops Sony's 0 ("Auto") and 0xffffffff ("n/a"), and the text + * exiftool prints for them without -n. + * + * @param array $data + * @return int|null + */ + protected function extractWhiteBalanceTemperature(array $data): ?int + { + foreach ($this->whiteBalanceTemperatureTags as $tag) { + if (!array_key_exists($tag, $data)) { + continue; + } + $kelvin = $this->normalizeInt($this->trim($data[$tag])); + if ($kelvin !== null + && $kelvin >= self::WHITEBALANCETEMPERATURE_MIN + && $kelvin <= self::WHITEBALANCETEMPERATURE_MAX) { + return $kelvin; + } + } + + return null; + } + /** * Extract GPS coordinates from formatted string * diff --git a/lib/PHPExif/Mapper/ImageMagick.php b/lib/PHPExif/Mapper/ImageMagick.php index 114e02ed..018acf48 100644 --- a/lib/PHPExif/Mapper/ImageMagick.php +++ b/lib/PHPExif/Mapper/ImageMagick.php @@ -26,6 +26,7 @@ class ImageMagick extends AbstractMapper public const DATETIMEORIGINAL = 'exif:DateTimeOriginal'; public const DESCRIPTION = 'exif:ImageDescription'; public const EXPOSURETIME = 'exif:ExposureTime'; + public const EXPOSUREBIAS = 'exif:ExposureBiasValue'; public const FILESIZE = 'filesize'; public const FILENAME = 'filename'; public const FOCALLENGTH = 'exif:FocalLength'; @@ -48,6 +49,7 @@ class ImageMagick extends AbstractMapper public const SOFTWARE = 'exif:Software'; public const XRESOLUTION = 'exif:XResolution'; public const YRESOLUTION = 'exif:YResolution'; + public const WHITEBALANCE = 'exif:WhiteBalance'; public const TITLE = 'iptc:title'; public const KEYWORDS = 'iptc:keywords'; public const COPYRIGHT_IPTC = 'iptc:copyright'; @@ -85,6 +87,7 @@ class ImageMagick extends AbstractMapper self::DATETIMEORIGINAL => Exif::CREATION_DATE, self::DESCRIPTION => Exif::DESCRIPTION, self::EXPOSURETIME => Exif::EXPOSURE, + self::EXPOSUREBIAS => Exif::EXPOSURE_BIAS, self::FILESIZE => Exif::FILESIZE, self::FILENAME => Exif::FILENAME, self::FOCALLENGTH => Exif::FOCAL_LENGTH, @@ -107,6 +110,7 @@ class ImageMagick extends AbstractMapper self::SOFTWARE => Exif::SOFTWARE, self::XRESOLUTION => Exif::HORIZONTAL_RESOLUTION, self::YRESOLUTION => Exif::VERTICAL_RESOLUTION, + self::WHITEBALANCE => Exif::WHITE_BALANCE, self::TITLE => Exif::TITLE, self::KEYWORDS => Exif::KEYWORDS, self::COPYRIGHT_IPTC => Exif::COPYRIGHT, @@ -267,6 +271,18 @@ public function mapRawData(array $data): array $value = [$value]; } break; + case self::EXPOSUREBIAS: + $value = $this->normalizeExposureBias($value); + if ($value === null) { + continue 2; + } + break; + case self::WHITEBALANCE: + $value = $this->normalizeWhiteBalance($value); + if ($value === null) { + continue 2; + } + break; case self::PROJECTIONTYPE: if (!is_string($value) || $value === '') { continue 2; diff --git a/lib/PHPExif/Mapper/Native.php b/lib/PHPExif/Mapper/Native.php index 1f51f820..0c532409 100644 --- a/lib/PHPExif/Mapper/Native.php +++ b/lib/PHPExif/Mapper/Native.php @@ -26,6 +26,7 @@ class Native extends AbstractMapper public const DATETIMEORIGINAL = 'DateTimeOriginal'; public const CREDIT = 'credit'; public const EXPOSURETIME = 'ExposureTime'; + public const EXPOSUREBIAS = 'ExposureBiasValue'; public const FILESIZE = 'FileSize'; public const FILENAME = 'FileName'; public const FOCALLENGTH = 'FocalLength'; @@ -41,6 +42,7 @@ class Native extends AbstractMapper public const SOFTWARE = 'Software'; public const SOURCE = 'source'; public const TITLE = 'title'; + public const WHITEBALANCE = 'WhiteBalance'; public const WIDTH = 'Width'; public const XRESOLUTION = 'XResolution'; public const YRESOLUTION = 'YResolution'; @@ -110,6 +112,7 @@ class Native extends AbstractMapper self::COLORSPACE => Exif::COLORSPACE, self::DATETIMEORIGINAL => Exif::CREATION_DATE, self::EXPOSURETIME => Exif::EXPOSURE, + self::EXPOSUREBIAS => Exif::EXPOSURE_BIAS, self::FILESIZE => Exif::FILESIZE, self::FILENAME => Exif::FILENAME, self::FOCALLENGTH => Exif::FOCAL_LENGTH, @@ -119,6 +122,7 @@ class Native extends AbstractMapper self::SOFTWARE => Exif::SOFTWARE, self::XRESOLUTION => Exif::HORIZONTAL_RESOLUTION, self::YRESOLUTION => Exif::VERTICAL_RESOLUTION, + self::WHITEBALANCE => Exif::WHITE_BALANCE, self::GPSLATITUDE => Exif::LATITUDE, self::GPSLONGITUDE => Exif::LONGITUDE, self::GPSALTITUDE => Exif::ALTITUDE, @@ -213,6 +217,18 @@ public function mapRawData(array $data): array $value = preg_replace('/.0$/', '', $value); } break; + case self::EXPOSUREBIAS: + $value = $this->normalizeExposureBias($value); + if ($value === null) { + continue 2; + } + break; + case self::WHITEBALANCE: + $value = $this->normalizeWhiteBalance($value); + if ($value === null) { + continue 2; + } + break; case self::FOCALLENGTH: $parts = explode('/', $value); // Avoid division by zero if focal length is invalid diff --git a/tests/PHPExif/Adapter/ExiftoolTest.php b/tests/PHPExif/Adapter/ExiftoolTest.php index 97dbbcc7..8d606ce8 100644 --- a/tests/PHPExif/Adapter/ExiftoolTest.php +++ b/tests/PHPExif/Adapter/ExiftoolTest.php @@ -144,4 +144,35 @@ public function testGetPanoramaDataFromFile() $this->assertSame(6000, $result->getCroppedAreaImageWidthPixels()); $this->assertSame(2000, $result->getCroppedAreaImageHeightPixels()); } + + /** + * gpano.jpg carries ExposureCompensation -2/3 EV and manual white balance. + * The Native, Exiftool and ImageMagick adapter tests assert the same values. + */ + #[Group('exiftool')] + public function testGetExposureBiasAndWhiteBalanceFromFile() + { + if ($this->adapter->getToolPath() === '') { + $this->markTestSkipped('exiftool is not available.'); + } + $result = $this->adapter->getExifFromFile(PHPEXIF_TEST_ROOT . '/files/gpano.jpg'); + + $this->assertSame(-0.67, $result->getExposureBias()); + $this->assertSame(1, $result->getWhiteBalance()); + } + + /** + * gpano.jpg carries XMP-crs:ColorTemperature 5500. + * Only the exiftool adapter reads the colour temperature. + */ + #[Group('exiftool')] + public function testGetWhiteBalanceTemperatureFromFile() + { + if ($this->adapter->getToolPath() === '') { + $this->markTestSkipped('exiftool is not available.'); + } + $result = $this->adapter->getExifFromFile(PHPEXIF_TEST_ROOT . '/files/gpano.jpg'); + + $this->assertSame(5500, $result->getWhiteBalanceTemperature()); + } } diff --git a/tests/PHPExif/Adapter/ImageMagickTest.php b/tests/PHPExif/Adapter/ImageMagickTest.php index b313027f..d8670801 100644 --- a/tests/PHPExif/Adapter/ImageMagickTest.php +++ b/tests/PHPExif/Adapter/ImageMagickTest.php @@ -56,4 +56,35 @@ public function testGetPanoramaDataFromFile() $this->assertSame(6000, $result->getCroppedAreaImageWidthPixels()); $this->assertSame(2000, $result->getCroppedAreaImageHeightPixels()); } + + /** + * gpano.jpg carries ExposureCompensation -2/3 EV and manual white balance. + * The Native, Exiftool and ImageMagick adapter tests assert the same values. + */ + #[Group('ImageMagick')] + public function testGetExposureBiasAndWhiteBalanceFromFile() + { + if (!extension_loaded('imagick')) { + $this->markTestSkipped('The imagick extension is not available.'); + } + $result = $this->adapter->getExifFromFile(PHPEXIF_TEST_ROOT . '/files/gpano.jpg'); + + $this->assertSame(-0.67, $result->getExposureBias()); + $this->assertSame(1, $result->getWhiteBalance()); + } + + /** + * The colour temperature is only read by the exiftool adapter, + * even though gpano.jpg carries XMP-crs:ColorTemperature 5500. + */ + #[Group('ImageMagick')] + public function testGetWhiteBalanceTemperatureIsNotAvailable() + { + if (!extension_loaded('imagick')) { + $this->markTestSkipped('The imagick extension is not available.'); + } + $result = $this->adapter->getExifFromFile(PHPEXIF_TEST_ROOT . '/files/gpano.jpg'); + + $this->assertFalse($result->getWhiteBalanceTemperature()); + } } diff --git a/tests/PHPExif/Adapter/NativeTest.php b/tests/PHPExif/Adapter/NativeTest.php index 106ce162..1dee1270 100644 --- a/tests/PHPExif/Adapter/NativeTest.php +++ b/tests/PHPExif/Adapter/NativeTest.php @@ -151,4 +151,35 @@ public function testGetSectionsAsArrayFromProperty() $this->assertEquals(Native::SECTIONS_AS_ARRAYS, $this->adapter->getSectionsAsArrays()); } + + /** + * gpano.jpg carries ExposureCompensation -2/3 EV and manual white balance. + * The Native, Exiftool and ImageMagick adapter tests assert the same values. + */ + #[Group('native')] + public function testGetExposureBiasAndWhiteBalanceFromFile() + { + if (!extension_loaded('exif')) { + $this->markTestSkipped('The exif extension is not available.'); + } + $result = $this->adapter->getExifFromFile(PHPEXIF_TEST_ROOT . '/files/gpano.jpg'); + + $this->assertSame(-0.67, $result->getExposureBias()); + $this->assertSame(1, $result->getWhiteBalance()); + } + + /** + * The colour temperature is only read by the exiftool adapter, + * even though gpano.jpg carries XMP-crs:ColorTemperature 5500. + */ + #[Group('native')] + public function testGetWhiteBalanceTemperatureIsNotAvailable() + { + if (!extension_loaded('exif')) { + $this->markTestSkipped('The exif extension is not available.'); + } + $result = $this->adapter->getExifFromFile(PHPEXIF_TEST_ROOT . '/files/gpano.jpg'); + + $this->assertFalse($result->getWhiteBalanceTemperature()); + } } diff --git a/tests/PHPExif/ExifTest.php b/tests/PHPExif/ExifTest.php index eb8f319b..a8a992e5 100644 --- a/tests/PHPExif/ExifTest.php +++ b/tests/PHPExif/ExifTest.php @@ -152,6 +152,9 @@ public static function providerUndefinedPropertiesReturnFalse() array('getCroppedAreaTopPixels'), array('getCroppedAreaImageWidthPixels'), array('getCroppedAreaImageHeightPixels'), + array('getExposureBias'), + array('getWhiteBalance'), + array('getWhiteBalanceTemperature'), ); } @@ -562,6 +565,67 @@ public function testGetCountry() $this->assertEquals($expected, $this->exif->getCountry()); } + #[Group('exif')] + public function testGetExposureBias() + { + $expected = -0.67; + $data[Exif::EXPOSURE_BIAS] = $expected; + $this->exif->setData($data); + $this->assertSame($expected, $this->exif->getExposureBias()); + } + + #[Group('exif')] + public function testSetExposureBias() + { + foreach (array(-0.67, 0.0, 1.5) as $expected) { + $result = $this->exif->setExposureBias($expected); + + $this->assertSame($this->exif, $result); + $this->assertSame($expected, $this->exif->getExposureBias()); + $this->assertSame(array(Exif::EXPOSURE_BIAS => $expected), $this->exif->getData()); + } + } + + #[Group('exif')] + public function testGetWhiteBalance() + { + $expected = 1; + $data[Exif::WHITE_BALANCE] = $expected; + $this->exif->setData($data); + $this->assertSame($expected, $this->exif->getWhiteBalance()); + } + + #[Group('exif')] + public function testSetWhiteBalance() + { + foreach (array(0, 1) as $expected) { + $result = $this->exif->setWhiteBalance($expected); + + $this->assertSame($this->exif, $result); + $this->assertSame($expected, $this->exif->getWhiteBalance()); + $this->assertSame(array(Exif::WHITE_BALANCE => $expected), $this->exif->getData()); + } + } + + #[Group('exif')] + public function testGetWhiteBalanceTemperature() + { + $expected = 5500; + $data[Exif::WHITE_BALANCE_TEMPERATURE] = $expected; + $this->exif->setData($data); + $this->assertSame($expected, $this->exif->getWhiteBalanceTemperature()); + } + + #[Group('exif')] + public function testSetWhiteBalanceTemperature() + { + $result = $this->exif->setWhiteBalanceTemperature(5500); + + $this->assertSame($this->exif, $result); + $this->assertSame(5500, $this->exif->getWhiteBalanceTemperature()); + $this->assertSame(array(Exif::WHITE_BALANCE_TEMPERATURE => 5500), $this->exif->getData()); + } + #[Group('exif')] public function testGetProjectionType() { @@ -695,6 +759,22 @@ public function testMutatorMethodsSetInProperty() $propertyValue = $reflProp->getValue($this->exif); $this->assertSame($pixels, $propertyValue[$value]); break; + case 'exposureBias': + $bias = -0.67; + $this->exif->$setter($bias); + $propertyValue = $reflProp->getValue($this->exif); + $this->assertSame($bias, $propertyValue[$value]); + break; + case 'whiteBalanceTemperature': + $this->exif->$setter(5500); + $propertyValue = $reflProp->getValue($this->exif); + $this->assertSame(5500, $propertyValue[$value]); + break; + case 'whiteBalance': + $this->exif->$setter(1); + $propertyValue = $reflProp->getValue($this->exif); + $this->assertSame(1, $propertyValue[$value]); + break; case 'UsePanoramaViewer': $this->exif->$setter(false); $propertyValue = $reflProp->getValue($this->exif); @@ -742,6 +822,8 @@ public function testAdapterConsistency() $name = $method->getName(); if ( strpos($name, 'get') !== 0 || $name === 'getRawData' || $name === 'getData' || $name === 'getColorSpace' || + // only the exiftool adapter reads the colour temperature (maker notes) + $name === 'getWhiteBalanceTemperature' || ($name === 'getLens' && $file === PHPEXIF_TEST_ROOT . '/files/dsc_5794.jpg') || ($file === PHPEXIF_TEST_ROOT . '/files/mongolia.jpeg' && ($name === 'getKeywords' || $name === 'getLens')) || ($file === PHPEXIF_TEST_ROOT . '/files/utf8.jpg' && ($name === 'getAuthor' || $name === 'getDescription')) @@ -787,7 +869,9 @@ public function testAdapterConsistency() // find all Getter methods on the results and compare its output foreach ($methods as $method) { $name = $method->getName(); - if (strpos($name, 'get') !== 0 || $name === 'getRawData' || $name === 'getData' || $name === 'getColorSpace') { + if (strpos($name, 'get') !== 0 || $name === 'getRawData' || $name === 'getData' || $name === 'getColorSpace' + || $name === 'getWhiteBalanceTemperature' + ) { continue; } $result_exif = $result_exif_exiftool->$name(); diff --git a/tests/PHPExif/Mapper/ExiftoolMapperTest.php b/tests/PHPExif/Mapper/ExiftoolMapperTest.php index c2dc70cf..bf57b76c 100644 --- a/tests/PHPExif/Mapper/ExiftoolMapperTest.php +++ b/tests/PHPExif/Mapper/ExiftoolMapperTest.php @@ -88,6 +88,16 @@ public function testMapRawDataMapsFieldsCorrectly() unset($map[Exiftool::CONTENTIDENTIFIER]); unset($map[Exiftool::CONTENTIDENTIFIER_QUICKTIME]); unset($map[Exiftool::PROJECTIONTYPE]); + unset($map[Exiftool::EXPOSUREBIAS]); + unset($map[Exiftool::WHITEBALANCE]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_CANON_ASSHOT]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_APPLE]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_SONY]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_FUJIFILM]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_PANASONIC]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_PENTAX]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_CANON]); + unset($map[Exiftool::WHITEBALANCETEMPERATURE_LIGHTROOM]); unset($map[Exiftool::USEPANORAMAVIEWER]); unset($map[Exiftool::FULLPANOWIDTHPIXELS]); unset($map[Exiftool::FULLPANOHEIGHTPIXELS]); @@ -798,4 +808,160 @@ public function testMapRawDataIgnoresNonNumericPanoCropFields($field, $key) $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); } } + + /** + * Data provider for testMapRawDataCorrectlyFormatsExposureBias + * + * @return array + */ + public static function providerExposureBias() + { + return array( + 'numeric -2/3' => array(-0.6666666667, -0.67), + 'numeric 0' => array(0, 0.0), + 'numeric 1' => array(1, 1.0), + 'rational -2/3' => array('-2/3', -0.67), + 'rational +1/3' => array('+1/3', 0.33), + 'rational 0/6' => array('0/6', 0.0), + 'rational 3/2' => array('3/2', 1.5), + 'string 0' => array('0', 0.0), + ); + } + + #[Group('mapper')] + #[DataProvider('providerExposureBias')] + public function testMapRawDataCorrectlyFormatsExposureBias($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + Exiftool::EXPOSUREBIAS => $raw, + )); + + $this->assertSame(array(Exif::EXPOSURE_BIAS => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidExposureBias() + { + foreach (array('abc', '', '1/0', '1/abc') as $raw) { + $mapped = $this->mapper->mapRawData(array( + Exiftool::EXPOSUREBIAS => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + /** + * Data provider for testMapRawDataCorrectlyFormatsWhiteBalance + * + * @return array + */ + public static function providerWhiteBalance() + { + return array( + 'int 0' => array(0, 0), + 'int 1' => array(1, 1), + 'string 0' => array('0', 0), + 'string 1' => array('1', 1), + 'label Auto' => array('Auto', 0), + 'label Manual' => array('Manual', 1), + ); + } + + #[Group('mapper')] + #[DataProvider('providerWhiteBalance')] + public function testMapRawDataCorrectlyFormatsWhiteBalance($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + Exiftool::WHITEBALANCE => $raw, + )); + + $this->assertSame(array(Exif::WHITE_BALANCE => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidWhiteBalance() + { + foreach (array('abc', '') as $raw) { + $mapped = $this->mapper->mapRawData(array( + Exiftool::WHITEBALANCE => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + /** + * Data provider: every exiftool tag that can hold the colour temperature + * + * @return array + */ + public static function providerWhiteBalanceTemperatureTags() + { + return array( + 'CANON_ASSHOT' => array(Exiftool::WHITEBALANCETEMPERATURE_CANON_ASSHOT), + 'APPLE' => array(Exiftool::WHITEBALANCETEMPERATURE_APPLE), + 'SONY' => array(Exiftool::WHITEBALANCETEMPERATURE_SONY), + 'FUJIFILM' => array(Exiftool::WHITEBALANCETEMPERATURE_FUJIFILM), + 'PANASONIC' => array(Exiftool::WHITEBALANCETEMPERATURE_PANASONIC), + 'PENTAX' => array(Exiftool::WHITEBALANCETEMPERATURE_PENTAX), + 'CANON' => array(Exiftool::WHITEBALANCETEMPERATURE_CANON), + 'LIGHTROOM' => array(Exiftool::WHITEBALANCETEMPERATURE_LIGHTROOM), + ); + } + + #[Group('mapper')] + #[DataProvider('providerWhiteBalanceTemperatureTags')] + public function testMapRawDataCorrectlyFormatsWhiteBalanceTemperature($field) + { + foreach (array(5500, '5500', ' 5500 ') as $raw) { + $mapped = $this->mapper->mapRawData(array($field => $raw)); + + $this->assertSame( + array(Exif::WHITE_BALANCE_TEMPERATURE => 5500), + $mapped, + 'value: ' . var_export($raw, true) + ); + } + } + + /** + * Sony writes 0 for "Auto" and 0xffffffff for "n/a"; + * without -n exiftool prints those as text. + */ + #[Group('mapper')] + #[DataProvider('providerWhiteBalanceTemperatureTags')] + public function testMapRawDataIgnoresInvalidWhiteBalanceTemperature($field) + { + foreach (array(0, '0', 4294967295, 'Auto', 'n/a', '', 'abc', 999, 50001) as $raw) { + $mapped = $this->mapper->mapRawData(array($field => $raw)); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + #[Group('mapper')] + public function testMapRawDataPrefersMeasuredWhiteBalanceTemperature() + { + // Lightroom and the manual Canon setting appear first, but the as-shot value wins + $mapped = $this->mapper->mapRawData(array( + Exiftool::WHITEBALANCETEMPERATURE_LIGHTROOM => 6500, + Exiftool::WHITEBALANCETEMPERATURE_CANON => 5200, + Exiftool::WHITEBALANCETEMPERATURE_CANON_ASSHOT => 4830, + )); + + $this->assertSame(array(Exif::WHITE_BALANCE_TEMPERATURE => 4830), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataFallsBackWhenWhiteBalanceTemperatureIsAuto() + { + // Sony "Auto" (0) is skipped in favour of the next valid tag + $mapped = $this->mapper->mapRawData(array( + Exiftool::WHITEBALANCETEMPERATURE_SONY => 0, + Exiftool::WHITEBALANCETEMPERATURE_LIGHTROOM => 5000, + )); + + $this->assertSame(array(Exif::WHITE_BALANCE_TEMPERATURE => 5000), $mapped); + } } diff --git a/tests/PHPExif/Mapper/ImageMagickMapperTest.php b/tests/PHPExif/Mapper/ImageMagickMapperTest.php index 01a40cfc..45f2cba8 100644 --- a/tests/PHPExif/Mapper/ImageMagickMapperTest.php +++ b/tests/PHPExif/Mapper/ImageMagickMapperTest.php @@ -51,6 +51,8 @@ public function testMapRawDataMapsFieldsCorrectly() unset($map[ImageMagick::IMAGEWIDTH_PNG]); unset($map[ImageMagick::COPYRIGHT_IPTC]); unset($map[ImageMagick::PROJECTIONTYPE]); + unset($map[ImageMagick::EXPOSUREBIAS]); + unset($map[ImageMagick::WHITEBALANCE]); unset($map[ImageMagick::USEPANORAMAVIEWER]); unset($map[ImageMagick::FULLPANOWIDTHPIXELS]); unset($map[ImageMagick::FULLPANOHEIGHTPIXELS]); @@ -623,4 +625,78 @@ public function testMapRawDataIgnoresNonNumericPanoCropFields($field, $key) $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); } } + + /** + * Data provider for testMapRawDataCorrectlyFormatsExposureBias + * + * @return array + */ + public static function providerExposureBias() + { + return array( + 'rational -2/3' => array('-2/3', -0.67), + 'rational +1/3' => array('+1/3', 0.33), + 'rational 0/6' => array('0/6', 0.0), + 'rational 3/2' => array('3/2', 1.5), + ); + } + + #[Group('mapper')] + #[DataProvider('providerExposureBias')] + public function testMapRawDataCorrectlyFormatsExposureBias($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::EXPOSUREBIAS => $raw, + )); + + $this->assertSame(array(Exif::EXPOSURE_BIAS => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidExposureBias() + { + foreach (array('abc', '', '1/0', '1/abc') as $raw) { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::EXPOSUREBIAS => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + /** + * Data provider for testMapRawDataCorrectlyFormatsWhiteBalance + * + * @return array + */ + public static function providerWhiteBalance() + { + return array( + 'string 0' => array('0', 0), + 'string 1' => array('1', 1), + ); + } + + #[Group('mapper')] + #[DataProvider('providerWhiteBalance')] + public function testMapRawDataCorrectlyFormatsWhiteBalance($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::WHITEBALANCE => $raw, + )); + + $this->assertSame(array(Exif::WHITE_BALANCE => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidWhiteBalance() + { + foreach (array('abc', '') as $raw) { + $mapped = $this->mapper->mapRawData(array( + ImageMagick::WHITEBALANCE => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } } diff --git a/tests/PHPExif/Mapper/NativeMapperTest.php b/tests/PHPExif/Mapper/NativeMapperTest.php index 287e7289..6c0911a3 100644 --- a/tests/PHPExif/Mapper/NativeMapperTest.php +++ b/tests/PHPExif/Mapper/NativeMapperTest.php @@ -1,7 +1,9 @@ array('-2/3', -0.67), + 'rational +1/3' => array('+1/3', 0.33), + 'rational 0/6' => array('0/6', 0.0), + 'rational 3/2' => array('3/2', 1.5), + ); + } + + #[Group('mapper')] + #[DataProvider('providerExposureBias')] + public function testMapRawDataCorrectlyFormatsExposureBias($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + Native::EXPOSUREBIAS => $raw, + )); + + $this->assertSame(array(Exif::EXPOSURE_BIAS => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidExposureBias() + { + foreach (array('abc', '', '1/0', '1/abc') as $raw) { + $mapped = $this->mapper->mapRawData(array( + Native::EXPOSUREBIAS => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } + + /** + * Data provider for testMapRawDataCorrectlyFormatsWhiteBalance + * + * @return array + */ + public static function providerWhiteBalance() + { + return array( + 'int 0' => array(0, 0), + 'int 1' => array(1, 1), + 'string 0' => array('0', 0), + 'string 1' => array('1', 1), + ); + } + + #[Group('mapper')] + #[DataProvider('providerWhiteBalance')] + public function testMapRawDataCorrectlyFormatsWhiteBalance($raw, $expected) + { + $mapped = $this->mapper->mapRawData(array( + Native::WHITEBALANCE => $raw, + )); + + $this->assertSame(array(Exif::WHITE_BALANCE => $expected), $mapped); + } + + #[Group('mapper')] + public function testMapRawDataIgnoresInvalidWhiteBalance() + { + foreach (array('abc', '') as $raw) { + $mapped = $this->mapper->mapRawData(array( + Native::WHITEBALANCE => $raw, + )); + + $this->assertSame(array(), $mapped, 'value: ' . var_export($raw, true)); + } + } } diff --git a/tests/files/gpano.jpg b/tests/files/gpano.jpg index f47b81d1b9532aa7d5697cbb51facbaa7221ad48..9b610fd5bfe94d1ee1ed06d97eb57b07da6c79f0 100644 GIT binary patch delta 335 zcmeC)!n0&6&xF^EODDcr#intIfkCrp^BhJSMj=%J1_tJgNo@@53=9l93=A3-lV35# zF==d>?8U6dq_Jdj6|*8gBLl+{76w+J3Lr~k&E!?gGdTYL|Njptz`WUu<&z4NchO`! zO&t!$U}sNHpyHDfC5aeK!O2c1~bt17@%oDv%r{vfemK1W(fl~ z0~bVGvxY$ktQY7q&6de;`cn8bpD{|qmA;!C*DuDT`E7GqzqIP+Y|R}hEdL)$)oz}$ z#ZF*y!$A$^W!OR#jMB=lv={VzzU=ofhy7_uVS9T0px%H+h#A8Pby5RY?JLYbv9q~ z-W^A7x12+Q~M7+<8K?tlD z=%_xs$wpc!YJCeBrQu3fFlqn|2N?mhfQb=kIM}$p4V(99NvkqHlzhB-@)kRR=Io>G O*+&_-XCGy<3