Skip to content

Commit f908413

Browse files
kamil4nagmat84
andauthored
Fix 1367 (#44)
* Accept 0 degrees/minutes/seconds * Fix argument types of some set methods * Add width and height data Co-authored-by: Matthias Nagel <[email protected]>
1 parent fcfa13e commit f908413

File tree

10 files changed

+146
-103
lines changed

10 files changed

+146
-103
lines changed

lib/PHPExif/Adapter/ImageMagick.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,16 @@ public function getExifFromFile(string $file) : Exif
4848
$data_filename = basename($file);
4949
$data_filesize = filesize($file);
5050
$mimeType = mime_content_type($file);
51-
$additional_data = array('MimeType' => $mimeType, 'filesize' => $data_filesize, 'filename' => $data_filename);
51+
$data_width = $im->getImageWidth();
52+
$data_height = $im->getImageHeight();
53+
$additional_data = [
54+
'MimeType' => $mimeType,
55+
'filesize' => $data_filesize,
56+
'filename' => $data_filename,
57+
'width' => $data_width,
58+
'height' => $data_height
59+
];
60+
5261
$data = array_merge($data_exif, $additional_data);
5362

5463
// map the data:

lib/PHPExif/Exif.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -793,10 +793,10 @@ public function getFileSize() : int|false
793793
/**
794794
* Sets the filesize
795795
*
796-
* @param string $value
796+
* @param int $value
797797
* @return Exif
798798
*/
799-
public function setFileSize(string $value) : Exif
799+
public function setFileSize(int $value) : Exif
800800
{
801801
$this->data[self::FILESIZE] = $value;
802802

@@ -942,10 +942,10 @@ public function getMake() : string|false
942942
/**
943943
* Sets the altitude value
944944
*
945-
* @param string $value
945+
* @param float $value
946946
* @return Exif
947947
*/
948-
public function setAltitude(string $value) : Exif
948+
public function setAltitude(float $value) : Exif
949949
{
950950
$this->data[self::ALTITUDE] = $value;
951951

@@ -969,10 +969,10 @@ public function getAltitude() : float|false
969969
/**
970970
* Sets the altitude value
971971
*
972-
* @param string $value
972+
* @param float $value
973973
* @return Exif
974974
*/
975-
public function setLongitude(string $value) : Exif
975+
public function setLongitude(float $value) : Exif
976976
{
977977
$this->data[self::LONGITUDE] = $value;
978978

@@ -996,10 +996,10 @@ public function getLongitude() : float|false
996996
/**
997997
* Sets the latitude value
998998
*
999-
* @param string $value
999+
* @param float $value
10001000
* @return Exif
10011001
*/
1002-
public function setLatitude(string $value) : Exif
1002+
public function setLatitude(float $value) : Exif
10031003
{
10041004
$this->data[self::LATITUDE] = $value;
10051005

@@ -1023,10 +1023,10 @@ public function getLatitude() : float|false
10231023
/**
10241024
* Sets the imgDirection value
10251025
*
1026-
* @param string $value
1026+
* @param float $value
10271027
* @return Exif
10281028
*/
1029-
public function setImgDirection(string $value) : Exif
1029+
public function setImgDirection(float $value) : Exif
10301030
{
10311031
$this->data[self::IMGDIRECTION] = $value;
10321032

lib/PHPExif/Mapper/Exiftool.php

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -281,36 +281,40 @@ public function mapRawData(array $data) : array
281281
break;
282282
case self::GPSLATITUDE_QUICKTIME:
283283
$value = $this->extractGPSCoordinates($value);
284+
if ($value === false) {
285+
continue 2;
286+
}
284287
break;
285288
case self::GPSLATITUDE:
286289
$latitudeRef = !array_key_exists('GPS:GPSLatitudeRef', $data) ?
287290
'N' : $data['GPS:GPSLatitudeRef'][0];
288291
$value = $this->extractGPSCoordinates($value);
289-
if ($value !== false) {
290-
$value = (strtoupper($latitudeRef) === 'S' ? -1.0 : 1.0) * $value;
291-
} else {
292-
$value = false;
292+
if ($value === false) {
293+
continue 2;
293294
}
294-
295+
$value *= strtoupper($latitudeRef) === 'S' ? -1 : 1;
295296
break;
296297
case self::GPSLONGITUDE_QUICKTIME:
297298
$value = $this->extractGPSCoordinates($value);
299+
if ($value === false) {
300+
continue 2;
301+
}
298302
break;
299303
case self::GPSLONGITUDE:
300304
$longitudeRef = !array_key_exists('GPS:GPSLongitudeRef', $data) ?
301305
'E' : $data['GPS:GPSLongitudeRef'][0];
302-
$value = $this->extractGPSCoordinates($value);
303-
if ($value !== false) {
304-
$value = (strtoupper($longitudeRef) === 'W' ? -1 : 1) * $value;
306+
$value = $this->extractGPSCoordinates($value);
307+
if ($value === false) {
308+
continue 2;
305309
}
306-
310+
$value *= strtoupper($longitudeRef) === 'W' ? -1 : 1;
307311
break;
308312
case self::GPSALTITUDE:
309313
$flip = 1;
310314
if (array_key_exists('GPS:GPSAltitudeRef', $data)) {
311315
$flip = ($data['GPS:GPSAltitudeRef'] === '1') ? -1 : 1;
312316
}
313-
$value = $flip * (float) $value;
317+
$value = $flip * (float) $value;
314318
break;
315319
case self::GPSALTITUDE_QUICKTIME:
316320
$flip = 1;
@@ -322,7 +326,7 @@ public function mapRawData(array $data) : array
322326
case self::IMAGEHEIGHT_VIDEO:
323327
case self::IMAGEWIDTH_VIDEO:
324328
preg_match("#^(\d+)[^\d]+(\d+)$#", $value, $matches);
325-
$value_splitted = array_slice($matches, 1);
329+
$value_split = array_slice($matches, 1);
326330
$rotate = false;
327331
if (array_key_exists('Composite:Rotation', $data)) {
328332
if ($data['Composite:Rotation'] === '90' || $data['Composite:Rotation'] === '270') {
@@ -331,16 +335,16 @@ public function mapRawData(array $data) : array
331335
}
332336
if (!array_key_exists(Exif::WIDTH, $mappedData)) {
333337
if (!($rotate)) {
334-
$mappedData[Exif::WIDTH] = intval($value_splitted[0]);
338+
$mappedData[Exif::WIDTH] = intval($value_split[0]);
335339
} else {
336-
$mappedData[Exif::WIDTH] = intval($value_splitted[1]);
340+
$mappedData[Exif::WIDTH] = intval($value_split[1]);
337341
}
338342
}
339343
if (!array_key_exists(Exif::HEIGHT, $mappedData)) {
340344
if (!($rotate)) {
341-
$mappedData[Exif::HEIGHT] = intval($value_splitted[1]);
345+
$mappedData[Exif::HEIGHT] = intval($value_split[1]);
342346
} else {
343-
$mappedData[Exif::HEIGHT] = intval($value_splitted[0]);
347+
$mappedData[Exif::HEIGHT] = intval($value_split[0]);
344348
}
345349
}
346350
continue 2;
@@ -374,13 +378,7 @@ public function mapRawData(array $data) : array
374378

375379
// add GPS coordinates, if available
376380
if ((isset($mappedData[Exif::LATITUDE])) && (isset($mappedData[Exif::LONGITUDE]))) {
377-
if (($mappedData[Exif::LATITUDE]!==false) && $mappedData[Exif::LONGITUDE]!==false) {
378-
$mappedData[Exif::GPS] = sprintf('%s,%s', $mappedData[Exif::LATITUDE], $mappedData[Exif::LONGITUDE]);
379-
} else {
380-
$mappedData[Exif::GPS] = false;
381-
}
382-
} else {
383-
unset($mappedData[Exif::GPS]);
381+
$mappedData[Exif::GPS] = sprintf('%s,%s', $mappedData[Exif::LATITUDE], $mappedData[Exif::LONGITUDE]);
384382
}
385383

386384
return $mappedData;

lib/PHPExif/Mapper/FFprobe.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ public function mapRawData(array $data) : array
149149
break;
150150
case self::FRAMERATE:
151151
$value = $this->normalizeComponent($value);
152+
if ($value === false) {
153+
continue 2;
154+
}
152155
break;
153156
case self::GPSLATITUDE:
154157
case self::GPSLONGITUDE:
@@ -168,7 +171,6 @@ public function mapRawData(array $data) : array
168171
$mappedData[Exif::LATITUDE] = $location_data['latitude'];
169172
$mappedData[Exif::LONGITUDE] = $location_data['longitude'];
170173
$mappedData[Exif::ALTITUDE] = $location_data['altitude'];
171-
//$value = $this->normalizeComponent($value);
172174
continue 2;
173175
}
174176

@@ -179,8 +181,6 @@ public function mapRawData(array $data) : array
179181
// add GPS coordinates, if available
180182
if ((isset($mappedData[Exif::LATITUDE])) && (isset($mappedData[Exif::LONGITUDE]))) {
181183
$mappedData[Exif::GPS] = sprintf('%s,%s', $mappedData[Exif::LATITUDE], $mappedData[Exif::LONGITUDE]);
182-
} else {
183-
unset($mappedData[Exif::GPS]);
184184
}
185185

186186
// Swap width and height if needed
@@ -236,9 +236,9 @@ protected function isFieldKnown(string &$field) : bool
236236
* Normalize component
237237
*
238238
* @param string $rational
239-
* @return float
239+
* @return float|false
240240
*/
241-
protected function normalizeComponent(string $rational) : float
241+
protected function normalizeComponent(string $rational) : float|false
242242
{
243243
$parts = explode('/', $rational, 2);
244244
if (count($parts) === 1) {
@@ -247,7 +247,7 @@ protected function normalizeComponent(string $rational) : float
247247
// case part[1] is 0, div by 0 is forbidden.
248248
// Catch case of one entry not being numeric
249249
if ($parts[1] === '0' || !is_numeric($parts[0]) || !is_numeric($parts[1])) {
250-
return (float) 0;
250+
return false;
251251
}
252252
return (float) $parts[0] / $parts[1];
253253
}

lib/PHPExif/Mapper/ImageMagick.php

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ class ImageMagick implements MapperInterface
4343
const GPSALTITUDE = 'exif:GPSAltitude';
4444
const IMAGEHEIGHT = 'exif:PixelYDimension';
4545
const IMAGEHEIGHT_PNG = 'png:IHDR.width,height';
46+
const HEIGHT = 'height';
4647
const IMAGEWIDTH = 'exif:PixelXDimension';
4748
const IMAGEWIDTH_PNG = 'png:IHDR.width,height';
49+
const WIDTH = 'width';
4850
const IMGDIRECTION = 'exif:GPSImgDirection';
4951
const ISO = 'exif:PhotographicSensitivity';
5052
const LENS = 'exif:LensModel';
@@ -78,8 +80,10 @@ class ImageMagick implements MapperInterface
7880
self::IMGDIRECTION => Exif::IMGDIRECTION,
7981
self::IMAGEHEIGHT => Exif::HEIGHT,
8082
self::IMAGEHEIGHT_PNG => Exif::HEIGHT,
83+
self::HEIGHT => Exif::HEIGHT,
8184
self::IMAGEWIDTH => Exif::WIDTH,
8285
self::IMAGEWIDTH_PNG => Exif::WIDTH,
86+
self::WIDTH => Exif::WIDTH,
8387
self::ISO => Exif::ISO,
8488
self::LENS => Exif::LENS,
8589
self::MAKE => Exif::MAKE,
@@ -115,7 +119,11 @@ public function mapRawData(array $data) : array
115119
// manipulate the value if necessary
116120
switch ($field) {
117121
case self::APERTURE:
118-
$value = sprintf('f/%01.1f', $this->normalizeComponent($value));
122+
$value = $this->normalizeComponent($value);
123+
if ($value === false) {
124+
continue 2;
125+
}
126+
$value = sprintf('f/%01.1f', $value);
119127
break;
120128
case self::CREATION_DATE:
121129
if (!isset($mappedData[Exif::CREATION_DATE])
@@ -150,6 +158,9 @@ public function mapRawData(array $data) : array
150158
break;
151159
case self::EXPOSURETIME:
152160
$value = $this->normalizeComponent($value);
161+
if ($value === false) {
162+
continue 2;
163+
}
153164
// Based on the source code of Exiftool (PrintExposureTime subroutine):
154165
// http://cpansearch.perl.org/src/EXIFTOOL/Image-ExifTool-9.90/lib/Image/ExifTool/Exif.pm
155166
if ($value < 0.25001 && $value > 0) {
@@ -165,6 +176,9 @@ public function mapRawData(array $data) : array
165176
$value = reset($focalLengthParts);
166177
}
167178
$value = $this->normalizeComponent($value);
179+
if ($value === false) {
180+
continue 2;
181+
}
168182
break;
169183
case self::ISO:
170184
$value = preg_split('/([\s,]+)/', $value)[0];
@@ -173,38 +187,43 @@ public function mapRawData(array $data) : array
173187
$latitudeRef = !array_key_exists('exif:GPSLatitudeRef', $data) ?
174188
'N' : $data['exif:GPSLatitudeRef'][0];
175189
$value = $this->extractGPSCoordinates($value);
176-
if ($value !== false) {
177-
$value = (strtoupper($latitudeRef) === 'S' ? -1.0 : 1.0) * $value;
178-
} else {
179-
$value = false;
190+
if ($value === false) {
191+
continue 2;
180192
}
181-
193+
$value *= strtoupper($latitudeRef) === 'S' ? -1 : 1;
182194
break;
183195
case self::GPSLONGITUDE:
184196
$longitudeRef = !array_key_exists('exif:GPSLongitudeRef', $data) ?
185197
'E' : $data['exif:GPSLongitudeRef'][0];
186198
$value = $this->extractGPSCoordinates($value);
187-
if ($value !== false) {
188-
$value = (strtoupper($longitudeRef) === 'W' ? -1 : 1) * $value;
199+
if ($value === false) {
200+
continue 2;
189201
}
190-
202+
$value *= strtoupper($longitudeRef) === 'W' ? -1 : 1;
191203
break;
192204
case self::GPSALTITUDE:
193205
$flip = 1;
194206
if (array_key_exists('exif:GPSAltitudeRef', $data)) {
195207
$flip = ($data['exif:GPSAltitudeRef'] === '1') ? -1 : 1;
196208
}
197-
$value = $flip * $this->normalizeComponent($value);
209+
$value = $this->normalizeComponent($value);
210+
if ($value === false) {
211+
continue 2;
212+
}
213+
$value *= $flip;
198214
break;
199215
case self::IMAGEHEIGHT_PNG:
200216
case self::IMAGEWIDTH_PNG:
201-
$value_splitted = explode(",", $value);
217+
$value_split = explode(",", $value);
202218

203-
$mappedData[Exif::WIDTH] = intval($value_splitted[0]);
204-
$mappedData[Exif::HEIGHT] = intval($value_splitted[1]);
219+
$mappedData[Exif::WIDTH] = intval($value_split[0]);
220+
$mappedData[Exif::HEIGHT] = intval($value_split[1]);
205221
continue 2;
206222
case self::IMGDIRECTION:
207223
$value = $this->normalizeComponent($value);
224+
if ($value === false) {
225+
continue 2;
226+
}
208227
break;
209228
}
210229
// set end result
@@ -213,13 +232,7 @@ public function mapRawData(array $data) : array
213232

214233
// add GPS coordinates, if available
215234
if ((isset($mappedData[Exif::LATITUDE])) && (isset($mappedData[Exif::LONGITUDE]))) {
216-
if (($mappedData[Exif::LATITUDE]!==false) && $mappedData[Exif::LONGITUDE]!==false) {
217-
$mappedData[Exif::GPS] = sprintf('%s,%s', $mappedData[Exif::LATITUDE], $mappedData[Exif::LONGITUDE]);
218-
} else {
219-
$mappedData[Exif::GPS] = false;
220-
}
221-
} else {
222-
unset($mappedData[Exif::GPS]);
235+
$mappedData[Exif::GPS] = sprintf('%s,%s', $mappedData[Exif::LATITUDE], $mappedData[Exif::LONGITUDE]);
223236
}
224237
return $mappedData;
225238
}
@@ -235,24 +248,27 @@ protected function extractGPSCoordinates(string $coordinates) : float|false
235248
if (is_numeric($coordinates) === true) {
236249
return ((float) $coordinates);
237250
} else {
238-
$m = '!^([1-9][0-9]*\/[1-9][0-9]*), ([1-9][0-9]*\/[1-9][0-9]*), ([1-9][0-9]*\/[1-9][0-9]*)!';
251+
$m = '!^([0-9]+\/[1-9][0-9]*), ([0-9]+\/[1-9][0-9]*), ([0-9]+\/[1-9][0-9]*)!';
239252
if (preg_match($m, $coordinates, $matches) === 0) {
240253
return false;
241254
}
242-
$degree = floatval($this->normalizeComponent($matches[1]));
243-
$minutes = floatval($this->normalizeComponent($matches[2]));
244-
$seconds = floatval($this->normalizeComponent($matches[3]));
245-
return $degree + $minutes / 60 + $seconds / 3600;
255+
$degrees = $this->normalizeComponent($matches[1]);
256+
$minutes = $this->normalizeComponent($matches[2]);
257+
$seconds = $this->normalizeComponent($matches[3]);
258+
if ($degrees === false || $minutes === false || $seconds === false) {
259+
return false;
260+
}
261+
return $degrees + $minutes / 60 + $seconds / 3600;
246262
}
247263
}
248264

249265
/**
250266
* Normalize component
251267
*
252268
* @param string $rational
253-
* @return float
269+
* @return float|false
254270
*/
255-
protected function normalizeComponent(string $rational) : float
271+
protected function normalizeComponent(string $rational) : float|false
256272
{
257273
$parts = explode('/', $rational, 2);
258274
if (count($parts) === 1) {
@@ -261,7 +277,7 @@ protected function normalizeComponent(string $rational) : float
261277
// case part[1] is 0, div by 0 is forbidden.
262278
// Catch case of one entry not being numeric
263279
if ($parts[1] === '0' || !is_numeric($parts[0]) || !is_numeric($parts[1])) {
264-
return (float) 0;
280+
return false;
265281
}
266282
return (float) $parts[0] / $parts[1];
267283
}

0 commit comments

Comments
 (0)