Don't fallback from uk to ru
[lhc/web/wiklou.git] / includes / media / XMPInfo.php
1 <?php
2 /**
3 * Definitions for XMPReader class.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Media
22 */
23
24 /**
25 * This class is just a container for a big array
26 * used by XMPReader to determine which XMP items to
27 * extract.
28 */
29 class XMPInfo {
30 /** Get the items array
31 * @return array XMP item configuration array.
32 */
33 public static function getItems() {
34 return self::$items;
35 }
36
37 /**
38 * XMPInfo::$items keeps a list of all the items
39 * we are interested to extract, as well as
40 * information about the item like what type
41 * it is.
42 *
43 * Format is an array of namespaces,
44 * each containing an array of tags
45 * each tag is an array of information about the
46 * tag, including:
47 * * map_group - What group (used for precedence during conflicts).
48 * * mode - What type of item (self::MODE_SIMPLE usually, see above for
49 * all values).
50 * * validate - Method to validate input. Could also post-process the
51 * input. A string value is assumed to be a method of
52 * XMPValidate. Can also take a array( 'className', 'methodName' ).
53 * * choices - Array of potential values (format of 'value' => true ).
54 * Only used with validateClosed.
55 * * rangeLow and rangeHigh - Alternative to choices for numeric ranges.
56 * Again for validateClosed only.
57 * * children - For MODE_STRUCT items, allowed children.
58 * * structPart - Indicates that this element can only appear as a member
59 * of a structure.
60 *
61 * Currently this just has a bunch of EXIF values as this class is only half-done.
62 */
63 static private $items = [
64 'http://ns.adobe.com/exif/1.0/' => [
65 'ApertureValue' => [
66 'map_group' => 'exif',
67 'mode' => XMPReader::MODE_SIMPLE,
68 'validate' => 'validateRational'
69 ],
70 'BrightnessValue' => [
71 'map_group' => 'exif',
72 'mode' => XMPReader::MODE_SIMPLE,
73 'validate' => 'validateRational'
74 ],
75 'CompressedBitsPerPixel' => [
76 'map_group' => 'exif',
77 'mode' => XMPReader::MODE_SIMPLE,
78 'validate' => 'validateRational'
79 ],
80 'DigitalZoomRatio' => [
81 'map_group' => 'exif',
82 'mode' => XMPReader::MODE_SIMPLE,
83 'validate' => 'validateRational'
84 ],
85 'ExposureBiasValue' => [
86 'map_group' => 'exif',
87 'mode' => XMPReader::MODE_SIMPLE,
88 'validate' => 'validateRational'
89 ],
90 'ExposureIndex' => [
91 'map_group' => 'exif',
92 'mode' => XMPReader::MODE_SIMPLE,
93 'validate' => 'validateRational'
94 ],
95 'ExposureTime' => [
96 'map_group' => 'exif',
97 'mode' => XMPReader::MODE_SIMPLE,
98 'validate' => 'validateRational'
99 ],
100 'FlashEnergy' => [
101 'map_group' => 'exif',
102 'mode' => XMPReader::MODE_SIMPLE,
103 'validate' => 'validateRational',
104 ],
105 'FNumber' => [
106 'map_group' => 'exif',
107 'mode' => XMPReader::MODE_SIMPLE,
108 'validate' => 'validateRational'
109 ],
110 'FocalLength' => [
111 'map_group' => 'exif',
112 'mode' => XMPReader::MODE_SIMPLE,
113 'validate' => 'validateRational'
114 ],
115 'FocalPlaneXResolution' => [
116 'map_group' => 'exif',
117 'mode' => XMPReader::MODE_SIMPLE,
118 'validate' => 'validateRational'
119 ],
120 'FocalPlaneYResolution' => [
121 'map_group' => 'exif',
122 'mode' => XMPReader::MODE_SIMPLE,
123 'validate' => 'validateRational'
124 ],
125 'GPSAltitude' => [
126 'map_group' => 'exif',
127 'mode' => XMPReader::MODE_SIMPLE,
128 'validate' => 'validateRational',
129 ],
130 'GPSDestBearing' => [
131 'map_group' => 'exif',
132 'mode' => XMPReader::MODE_SIMPLE,
133 'validate' => 'validateRational'
134 ],
135 'GPSDestDistance' => [
136 'map_group' => 'exif',
137 'mode' => XMPReader::MODE_SIMPLE,
138 'validate' => 'validateRational'
139 ],
140 'GPSDOP' => [
141 'map_group' => 'exif',
142 'mode' => XMPReader::MODE_SIMPLE,
143 'validate' => 'validateRational'
144 ],
145 'GPSImgDirection' => [
146 'map_group' => 'exif',
147 'mode' => XMPReader::MODE_SIMPLE,
148 'validate' => 'validateRational'
149 ],
150 'GPSSpeed' => [
151 'map_group' => 'exif',
152 'mode' => XMPReader::MODE_SIMPLE,
153 'validate' => 'validateRational'
154 ],
155 'GPSTrack' => [
156 'map_group' => 'exif',
157 'mode' => XMPReader::MODE_SIMPLE,
158 'validate' => 'validateRational'
159 ],
160 'MaxApertureValue' => [
161 'map_group' => 'exif',
162 'mode' => XMPReader::MODE_SIMPLE,
163 'validate' => 'validateRational'
164 ],
165 'ShutterSpeedValue' => [
166 'map_group' => 'exif',
167 'mode' => XMPReader::MODE_SIMPLE,
168 'validate' => 'validateRational'
169 ],
170 'SubjectDistance' => [
171 'map_group' => 'exif',
172 'mode' => XMPReader::MODE_SIMPLE,
173 'validate' => 'validateRational'
174 ],
175 /* Flash */
176 'Flash' => [
177 'mode' => XMPReader::MODE_STRUCT,
178 'children' => [
179 'Fired' => true,
180 'Function' => true,
181 'Mode' => true,
182 'RedEyeMode' => true,
183 'Return' => true,
184 ],
185 'validate' => 'validateFlash',
186 'map_group' => 'exif',
187 ],
188 'Fired' => [
189 'map_group' => 'exif',
190 'validate' => 'validateBoolean',
191 'mode' => XMPReader::MODE_SIMPLE,
192 'structPart' => true,
193 ],
194 'Function' => [
195 'map_group' => 'exif',
196 'validate' => 'validateBoolean',
197 'mode' => XMPReader::MODE_SIMPLE,
198 'structPart' => true,
199 ],
200 'Mode' => [
201 'map_group' => 'exif',
202 'validate' => 'validateClosed',
203 'mode' => XMPReader::MODE_SIMPLE,
204 'choices' => [ '0' => true, '1' => true,
205 '2' => true, '3' => true ],
206 'structPart' => true,
207 ],
208 'Return' => [
209 'map_group' => 'exif',
210 'validate' => 'validateClosed',
211 'mode' => XMPReader::MODE_SIMPLE,
212 'choices' => [ '0' => true,
213 '2' => true, '3' => true ],
214 'structPart' => true,
215 ],
216 'RedEyeMode' => [
217 'map_group' => 'exif',
218 'validate' => 'validateBoolean',
219 'mode' => XMPReader::MODE_SIMPLE,
220 'structPart' => true,
221 ],
222 /* End Flash */
223 'ISOSpeedRatings' => [
224 'map_group' => 'exif',
225 'mode' => XMPReader::MODE_SEQ,
226 'validate' => 'validateInteger'
227 ],
228 /* end rational things */
229 'ColorSpace' => [
230 'map_group' => 'exif',
231 'mode' => XMPReader::MODE_SIMPLE,
232 'validate' => 'validateClosed',
233 'choices' => [ '1' => true, '65535' => true ],
234 ],
235 'ComponentsConfiguration' => [
236 'map_group' => 'exif',
237 'mode' => XMPReader::MODE_SEQ,
238 'validate' => 'validateClosed',
239 'choices' => [ '1' => true, '2' => true, '3' => true, '4' => true,
240 '5' => true, '6' => true ]
241 ],
242 'Contrast' => [
243 'map_group' => 'exif',
244 'mode' => XMPReader::MODE_SIMPLE,
245 'validate' => 'validateClosed',
246 'choices' => [ '0' => true, '1' => true, '2' => true ]
247 ],
248 'CustomRendered' => [
249 'map_group' => 'exif',
250 'mode' => XMPReader::MODE_SIMPLE,
251 'validate' => 'validateClosed',
252 'choices' => [ '0' => true, '1' => true ]
253 ],
254 'DateTimeOriginal' => [
255 'map_group' => 'exif',
256 'mode' => XMPReader::MODE_SIMPLE,
257 'validate' => 'validateDate',
258 ],
259 'DateTimeDigitized' => [ /* xmp:CreateDate */
260 'map_group' => 'exif',
261 'mode' => XMPReader::MODE_SIMPLE,
262 'validate' => 'validateDate',
263 ],
264 /* todo: there might be interesting information in
265 * exif:DeviceSettingDescription, but need to find an
266 * example
267 */
268 'ExifVersion' => [
269 'map_group' => 'exif',
270 'mode' => XMPReader::MODE_SIMPLE,
271 ],
272 'ExposureMode' => [
273 'map_group' => 'exif',
274 'mode' => XMPReader::MODE_SIMPLE,
275 'validate' => 'validateClosed',
276 'rangeLow' => 0,
277 'rangeHigh' => 2,
278 ],
279 'ExposureProgram' => [
280 'map_group' => 'exif',
281 'mode' => XMPReader::MODE_SIMPLE,
282 'validate' => 'validateClosed',
283 'rangeLow' => 0,
284 'rangeHigh' => 8,
285 ],
286 'FileSource' => [
287 'map_group' => 'exif',
288 'mode' => XMPReader::MODE_SIMPLE,
289 'validate' => 'validateClosed',
290 'choices' => [ '3' => true ]
291 ],
292 'FlashpixVersion' => [
293 'map_group' => 'exif',
294 'mode' => XMPReader::MODE_SIMPLE,
295 ],
296 'FocalLengthIn35mmFilm' => [
297 'map_group' => 'exif',
298 'mode' => XMPReader::MODE_SIMPLE,
299 'validate' => 'validateInteger',
300 ],
301 'FocalPlaneResolutionUnit' => [
302 'map_group' => 'exif',
303 'mode' => XMPReader::MODE_SIMPLE,
304 'validate' => 'validateClosed',
305 'choices' => [ '2' => true, '3' => true ],
306 ],
307 'GainControl' => [
308 'map_group' => 'exif',
309 'mode' => XMPReader::MODE_SIMPLE,
310 'validate' => 'validateClosed',
311 'rangeLow' => 0,
312 'rangeHigh' => 4,
313 ],
314 /* this value is post-processed out later */
315 'GPSAltitudeRef' => [
316 'map_group' => 'exif',
317 'mode' => XMPReader::MODE_SIMPLE,
318 'validate' => 'validateClosed',
319 'choices' => [ '0' => true, '1' => true ],
320 ],
321 'GPSAreaInformation' => [
322 'map_group' => 'exif',
323 'mode' => XMPReader::MODE_SIMPLE,
324 ],
325 'GPSDestBearingRef' => [
326 'map_group' => 'exif',
327 'mode' => XMPReader::MODE_SIMPLE,
328 'validate' => 'validateClosed',
329 'choices' => [ 'T' => true, 'M' => true ],
330 ],
331 'GPSDestDistanceRef' => [
332 'map_group' => 'exif',
333 'mode' => XMPReader::MODE_SIMPLE,
334 'validate' => 'validateClosed',
335 'choices' => [ 'K' => true, 'M' => true,
336 'N' => true ],
337 ],
338 'GPSDestLatitude' => [
339 'map_group' => 'exif',
340 'mode' => XMPReader::MODE_SIMPLE,
341 'validate' => 'validateGPS',
342 ],
343 'GPSDestLongitude' => [
344 'map_group' => 'exif',
345 'mode' => XMPReader::MODE_SIMPLE,
346 'validate' => 'validateGPS',
347 ],
348 'GPSDifferential' => [
349 'map_group' => 'exif',
350 'mode' => XMPReader::MODE_SIMPLE,
351 'validate' => 'validateClosed',
352 'choices' => [ '0' => true, '1' => true ],
353 ],
354 'GPSImgDirectionRef' => [
355 'map_group' => 'exif',
356 'mode' => XMPReader::MODE_SIMPLE,
357 'validate' => 'validateClosed',
358 'choices' => [ 'T' => true, 'M' => true ],
359 ],
360 'GPSLatitude' => [
361 'map_group' => 'exif',
362 'mode' => XMPReader::MODE_SIMPLE,
363 'validate' => 'validateGPS',
364 ],
365 'GPSLongitude' => [
366 'map_group' => 'exif',
367 'mode' => XMPReader::MODE_SIMPLE,
368 'validate' => 'validateGPS',
369 ],
370 'GPSMapDatum' => [
371 'map_group' => 'exif',
372 'mode' => XMPReader::MODE_SIMPLE,
373 ],
374 'GPSMeasureMode' => [
375 'map_group' => 'exif',
376 'mode' => XMPReader::MODE_SIMPLE,
377 'validate' => 'validateClosed',
378 'choices' => [ '2' => true, '3' => true ]
379 ],
380 'GPSProcessingMethod' => [
381 'map_group' => 'exif',
382 'mode' => XMPReader::MODE_SIMPLE,
383 ],
384 'GPSSatellites' => [
385 'map_group' => 'exif',
386 'mode' => XMPReader::MODE_SIMPLE,
387 ],
388 'GPSSpeedRef' => [
389 'map_group' => 'exif',
390 'mode' => XMPReader::MODE_SIMPLE,
391 'validate' => 'validateClosed',
392 'choices' => [ 'K' => true, 'M' => true,
393 'N' => true ],
394 ],
395 'GPSStatus' => [
396 'map_group' => 'exif',
397 'mode' => XMPReader::MODE_SIMPLE,
398 'validate' => 'validateClosed',
399 'choices' => [ 'A' => true, 'V' => true ]
400 ],
401 'GPSTimeStamp' => [
402 'map_group' => 'exif',
403 // Note: in exif, GPSDateStamp does not include
404 // the time, where here it does.
405 'map_name' => 'GPSDateStamp',
406 'mode' => XMPReader::MODE_SIMPLE,
407 'validate' => 'validateDate',
408 ],
409 'GPSTrackRef' => [
410 'map_group' => 'exif',
411 'mode' => XMPReader::MODE_SIMPLE,
412 'validate' => 'validateClosed',
413 'choices' => [ 'T' => true, 'M' => true ]
414 ],
415 'GPSVersionID' => [
416 'map_group' => 'exif',
417 'mode' => XMPReader::MODE_SIMPLE,
418 ],
419 'ImageUniqueID' => [
420 'map_group' => 'exif',
421 'mode' => XMPReader::MODE_SIMPLE,
422 ],
423 'LightSource' => [
424 'map_group' => 'exif',
425 'mode' => XMPReader::MODE_SIMPLE,
426 'validate' => 'validateClosed',
427 /* can't use a range, as it skips... */
428 'choices' => [ '0' => true, '1' => true,
429 '2' => true, '3' => true, '4' => true,
430 '9' => true, '10' => true, '11' => true,
431 '12' => true, '13' => true,
432 '14' => true, '15' => true,
433 '17' => true, '18' => true,
434 '19' => true, '20' => true,
435 '21' => true, '22' => true,
436 '23' => true, '24' => true,
437 '255' => true,
438 ],
439 ],
440 'MeteringMode' => [
441 'map_group' => 'exif',
442 'mode' => XMPReader::MODE_SIMPLE,
443 'validate' => 'validateClosed',
444 'rangeLow' => 0,
445 'rangeHigh' => 6,
446 'choices' => [ '255' => true ],
447 ],
448 /* Pixel(X|Y)Dimension are rather useless, but for
449 * completeness since we do it with exif.
450 */
451 'PixelXDimension' => [
452 'map_group' => 'exif',
453 'mode' => XMPReader::MODE_SIMPLE,
454 'validate' => 'validateInteger',
455 ],
456 'PixelYDimension' => [
457 'map_group' => 'exif',
458 'mode' => XMPReader::MODE_SIMPLE,
459 'validate' => 'validateInteger',
460 ],
461 'Saturation' => [
462 'map_group' => 'exif',
463 'mode' => XMPReader::MODE_SIMPLE,
464 'validate' => 'validateClosed',
465 'rangeLow' => 0,
466 'rangeHigh' => 2,
467 ],
468 'SceneCaptureType' => [
469 'map_group' => 'exif',
470 'mode' => XMPReader::MODE_SIMPLE,
471 'validate' => 'validateClosed',
472 'rangeLow' => 0,
473 'rangeHigh' => 3,
474 ],
475 'SceneType' => [
476 'map_group' => 'exif',
477 'mode' => XMPReader::MODE_SIMPLE,
478 'validate' => 'validateClosed',
479 'choices' => [ '1' => true ],
480 ],
481 // Note, 6 is not valid SensingMethod.
482 'SensingMethod' => [
483 'map_group' => 'exif',
484 'mode' => XMPReader::MODE_SIMPLE,
485 'validate' => 'validateClosed',
486 'rangeLow' => 1,
487 'rangeHigh' => 5,
488 'choices' => [ '7' => true, 8 => true ],
489 ],
490 'Sharpness' => [
491 'map_group' => 'exif',
492 'mode' => XMPReader::MODE_SIMPLE,
493 'validate' => 'validateClosed',
494 'rangeLow' => 0,
495 'rangeHigh' => 2,
496 ],
497 'SpectralSensitivity' => [
498 'map_group' => 'exif',
499 'mode' => XMPReader::MODE_SIMPLE,
500 ],
501 // This tag should perhaps be displayed to user better.
502 'SubjectArea' => [
503 'map_group' => 'exif',
504 'mode' => XMPReader::MODE_SEQ,
505 'validate' => 'validateInteger',
506 ],
507 'SubjectDistanceRange' => [
508 'map_group' => 'exif',
509 'mode' => XMPReader::MODE_SIMPLE,
510 'validate' => 'validateClosed',
511 'rangeLow' => 0,
512 'rangeHigh' => 3,
513 ],
514 'SubjectLocation' => [
515 'map_group' => 'exif',
516 'mode' => XMPReader::MODE_SEQ,
517 'validate' => 'validateInteger',
518 ],
519 'UserComment' => [
520 'map_group' => 'exif',
521 'mode' => XMPReader::MODE_LANG,
522 ],
523 'WhiteBalance' => [
524 'map_group' => 'exif',
525 'mode' => XMPReader::MODE_SIMPLE,
526 'validate' => 'validateClosed',
527 'choices' => [ '0' => true, '1' => true ]
528 ],
529 ],
530 'http://ns.adobe.com/tiff/1.0/' => [
531 'Artist' => [
532 'map_group' => 'exif',
533 'mode' => XMPReader::MODE_SIMPLE,
534 ],
535 'BitsPerSample' => [
536 'map_group' => 'exif',
537 'mode' => XMPReader::MODE_SEQ,
538 'validate' => 'validateInteger',
539 ],
540 'Compression' => [
541 'map_group' => 'exif',
542 'mode' => XMPReader::MODE_SIMPLE,
543 'validate' => 'validateClosed',
544 'choices' => [ '1' => true, '6' => true ],
545 ],
546 /* this prop should not be used in XMP. dc:rights is the correct prop */
547 'Copyright' => [
548 'map_group' => 'exif',
549 'mode' => XMPReader::MODE_LANG,
550 ],
551 'DateTime' => [ /* proper prop is xmp:ModifyDate */
552 'map_group' => 'exif',
553 'mode' => XMPReader::MODE_SIMPLE,
554 'validate' => 'validateDate',
555 ],
556 'ImageDescription' => [ /* proper one is dc:description */
557 'map_group' => 'exif',
558 'mode' => XMPReader::MODE_LANG,
559 ],
560 'ImageLength' => [
561 'map_group' => 'exif',
562 'mode' => XMPReader::MODE_SIMPLE,
563 'validate' => 'validateInteger',
564 ],
565 'ImageWidth' => [
566 'map_group' => 'exif',
567 'mode' => XMPReader::MODE_SIMPLE,
568 'validate' => 'validateInteger',
569 ],
570 'Make' => [
571 'map_group' => 'exif',
572 'mode' => XMPReader::MODE_SIMPLE,
573 ],
574 'Model' => [
575 'map_group' => 'exif',
576 'mode' => XMPReader::MODE_SIMPLE,
577 ],
578 /**** Do not extract this property
579 * It interferes with auto exif rotation.
580 * 'Orientation' => array(
581 * 'map_group' => 'exif',
582 * 'mode' => XMPReader::MODE_SIMPLE,
583 * 'validate' => 'validateClosed',
584 * 'choices' => array( '1' => true, '2' => true, '3' => true, '4' => true, 5 => true,
585 * '6' => true, '7' => true, '8' => true ),
586 *),
587 ******/
588 'PhotometricInterpretation' => [
589 'map_group' => 'exif',
590 'mode' => XMPReader::MODE_SIMPLE,
591 'validate' => 'validateClosed',
592 'choices' => [ '2' => true, '6' => true ],
593 ],
594 'PlanerConfiguration' => [
595 'map_group' => 'exif',
596 'mode' => XMPReader::MODE_SIMPLE,
597 'validate' => 'validateClosed',
598 'choices' => [ '1' => true, '2' => true ],
599 ],
600 'PrimaryChromaticities' => [
601 'map_group' => 'exif',
602 'mode' => XMPReader::MODE_SEQ,
603 'validate' => 'validateRational',
604 ],
605 'ReferenceBlackWhite' => [
606 'map_group' => 'exif',
607 'mode' => XMPReader::MODE_SEQ,
608 'validate' => 'validateRational',
609 ],
610 'ResolutionUnit' => [
611 'map_group' => 'exif',
612 'mode' => XMPReader::MODE_SIMPLE,
613 'validate' => 'validateClosed',
614 'choices' => [ '2' => true, '3' => true ],
615 ],
616 'SamplesPerPixel' => [
617 'map_group' => 'exif',
618 'mode' => XMPReader::MODE_SIMPLE,
619 'validate' => 'validateInteger',
620 ],
621 'Software' => [ /* see xmp:CreatorTool */
622 'map_group' => 'exif',
623 'mode' => XMPReader::MODE_SIMPLE,
624 ],
625 /* ignore TransferFunction */
626 'WhitePoint' => [
627 'map_group' => 'exif',
628 'mode' => XMPReader::MODE_SEQ,
629 'validate' => 'validateRational',
630 ],
631 'XResolution' => [
632 'map_group' => 'exif',
633 'mode' => XMPReader::MODE_SIMPLE,
634 'validate' => 'validateRational',
635 ],
636 'YResolution' => [
637 'map_group' => 'exif',
638 'mode' => XMPReader::MODE_SIMPLE,
639 'validate' => 'validateRational',
640 ],
641 'YCbCrCoefficients' => [
642 'map_group' => 'exif',
643 'mode' => XMPReader::MODE_SEQ,
644 'validate' => 'validateRational',
645 ],
646 'YCbCrPositioning' => [
647 'map_group' => 'exif',
648 'mode' => XMPReader::MODE_SIMPLE,
649 'validate' => 'validateClosed',
650 'choices' => [ '1' => true, '2' => true ],
651 ],
652 /********
653 * Disable extracting this property (bug 31944)
654 * Several files have a string instead of a Seq
655 * for this property. XMPReader doesn't handle
656 * mismatched types very gracefully (it marks
657 * the entire file as invalid, instead of just
658 * the relavent prop). Since this prop
659 * doesn't communicate all that useful information
660 * just disable this prop for now, until such
661 * XMPReader is more graceful (bug 32172)
662 * 'YCbCrSubSampling' => array(
663 * 'map_group' => 'exif',
664 * 'mode' => XMPReader::MODE_SEQ,
665 * 'validate' => 'validateClosed',
666 * 'choices' => array( '1' => true, '2' => true ),
667 * ),
668 */
669 ],
670 'http://ns.adobe.com/exif/1.0/aux/' => [
671 'Lens' => [
672 'map_group' => 'exif',
673 'mode' => XMPReader::MODE_SIMPLE,
674 ],
675 'SerialNumber' => [
676 'map_group' => 'exif',
677 'mode' => XMPReader::MODE_SIMPLE,
678 ],
679 'OwnerName' => [
680 'map_group' => 'exif',
681 'map_name' => 'CameraOwnerName',
682 'mode' => XMPReader::MODE_SIMPLE,
683 ],
684 ],
685 'http://purl.org/dc/elements/1.1/' => [
686 'title' => [
687 'map_group' => 'general',
688 'map_name' => 'ObjectName',
689 'mode' => XMPReader::MODE_LANG
690 ],
691 'description' => [
692 'map_group' => 'general',
693 'map_name' => 'ImageDescription',
694 'mode' => XMPReader::MODE_LANG
695 ],
696 'contributor' => [
697 'map_group' => 'general',
698 'map_name' => 'dc-contributor',
699 'mode' => XMPReader::MODE_BAG
700 ],
701 'coverage' => [
702 'map_group' => 'general',
703 'map_name' => 'dc-coverage',
704 'mode' => XMPReader::MODE_SIMPLE,
705 ],
706 'creator' => [
707 'map_group' => 'general',
708 'map_name' => 'Artist', // map with exif Artist, iptc byline (2:80)
709 'mode' => XMPReader::MODE_SEQ,
710 ],
711 'date' => [
712 'map_group' => 'general',
713 // Note, not mapped with other date properties, as this type of date is
714 // non-specific: "A point or period of time associated with an event in
715 // the lifecycle of the resource"
716 'map_name' => 'dc-date',
717 'mode' => XMPReader::MODE_SEQ,
718 'validate' => 'validateDate',
719 ],
720 /* Do not extract dc:format, as we've got better ways to determine MIME type */
721 'identifier' => [
722 'map_group' => 'deprecated',
723 'map_name' => 'Identifier',
724 'mode' => XMPReader::MODE_SIMPLE,
725 ],
726 'language' => [
727 'map_group' => 'general',
728 'map_name' => 'LanguageCode', /* mapped with iptc 2:135 */
729 'mode' => XMPReader::MODE_BAG,
730 'validate' => 'validateLangCode',
731 ],
732 'publisher' => [
733 'map_group' => 'general',
734 'map_name' => 'dc-publisher',
735 'mode' => XMPReader::MODE_BAG,
736 ],
737 // for related images/resources
738 'relation' => [
739 'map_group' => 'general',
740 'map_name' => 'dc-relation',
741 'mode' => XMPReader::MODE_BAG,
742 ],
743 'rights' => [
744 'map_group' => 'general',
745 'map_name' => 'Copyright',
746 'mode' => XMPReader::MODE_LANG,
747 ],
748 // Note: source is not mapped with iptc source, since iptc
749 // source describes the source of the image in terms of a person
750 // who provided the image, where this is to describe an image that the
751 // current one is based on.
752 'source' => [
753 'map_group' => 'general',
754 'map_name' => 'dc-source',
755 'mode' => XMPReader::MODE_SIMPLE,
756 ],
757 'subject' => [
758 'map_group' => 'general',
759 'map_name' => 'Keywords', /* maps to iptc 2:25 */
760 'mode' => XMPReader::MODE_BAG,
761 ],
762 'type' => [
763 'map_group' => 'general',
764 'map_name' => 'dc-type',
765 'mode' => XMPReader::MODE_BAG,
766 ],
767 ],
768 'http://ns.adobe.com/xap/1.0/' => [
769 'CreateDate' => [
770 'map_group' => 'general',
771 'map_name' => 'DateTimeDigitized',
772 'mode' => XMPReader::MODE_SIMPLE,
773 'validate' => 'validateDate',
774 ],
775 'CreatorTool' => [
776 'map_group' => 'general',
777 'map_name' => 'Software',
778 'mode' => XMPReader::MODE_SIMPLE
779 ],
780 'Identifier' => [
781 'map_group' => 'general',
782 'mode' => XMPReader::MODE_BAG,
783 ],
784 'Label' => [
785 'map_group' => 'general',
786 'mode' => XMPReader::MODE_SIMPLE,
787 ],
788 'ModifyDate' => [
789 'map_group' => 'general',
790 'mode' => XMPReader::MODE_SIMPLE,
791 'map_name' => 'DateTime',
792 'validate' => 'validateDate',
793 ],
794 'MetadataDate' => [
795 'map_group' => 'general',
796 'mode' => XMPReader::MODE_SIMPLE,
797 // map_name to be consistent with other date names.
798 'map_name' => 'DateTimeMetadata',
799 'validate' => 'validateDate',
800 ],
801 'Nickname' => [
802 'map_group' => 'general',
803 'mode' => XMPReader::MODE_SIMPLE,
804 ],
805 'Rating' => [
806 'map_group' => 'general',
807 'mode' => XMPReader::MODE_SIMPLE,
808 'validate' => 'validateRating',
809 ],
810 ],
811 'http://ns.adobe.com/xap/1.0/rights/' => [
812 'Certificate' => [
813 'map_group' => 'general',
814 'map_name' => 'RightsCertificate',
815 'mode' => XMPReader::MODE_SIMPLE,
816 ],
817 'Marked' => [
818 'map_group' => 'general',
819 'map_name' => 'Copyrighted',
820 'mode' => XMPReader::MODE_SIMPLE,
821 'validate' => 'validateBoolean',
822 ],
823 'Owner' => [
824 'map_group' => 'general',
825 'map_name' => 'CopyrightOwner',
826 'mode' => XMPReader::MODE_BAG,
827 ],
828 // this seems similar to dc:rights.
829 'UsageTerms' => [
830 'map_group' => 'general',
831 'mode' => XMPReader::MODE_LANG,
832 ],
833 'WebStatement' => [
834 'map_group' => 'general',
835 'mode' => XMPReader::MODE_SIMPLE,
836 ],
837 ],
838 // XMP media management.
839 'http://ns.adobe.com/xap/1.0/mm/' => [
840 // if we extract the exif UniqueImageID, might
841 // as well do this too.
842 'OriginalDocumentID' => [
843 'map_group' => 'general',
844 'mode' => XMPReader::MODE_SIMPLE,
845 ],
846 // It might also be useful to do xmpMM:LastURL
847 // and xmpMM:DerivedFrom as you can potentially,
848 // get the url of this document/source for this
849 // document. However whats more likely is you'd
850 // get a file:// url for the path of the doc,
851 // which is somewhat of a privacy issue.
852 ],
853 'http://creativecommons.org/ns#' => [
854 'license' => [
855 'map_name' => 'LicenseUrl',
856 'map_group' => 'general',
857 'mode' => XMPReader::MODE_SIMPLE,
858 ],
859 'morePermissions' => [
860 'map_name' => 'MorePermissionsUrl',
861 'map_group' => 'general',
862 'mode' => XMPReader::MODE_SIMPLE,
863 ],
864 'attributionURL' => [
865 'map_group' => 'general',
866 'map_name' => 'AttributionUrl',
867 'mode' => XMPReader::MODE_SIMPLE,
868 ],
869 'attributionName' => [
870 'map_group' => 'general',
871 'map_name' => 'PreferredAttributionName',
872 'mode' => XMPReader::MODE_SIMPLE,
873 ],
874 ],
875 // Note, this property affects how jpeg metadata is extracted.
876 'http://ns.adobe.com/xmp/note/' => [
877 'HasExtendedXMP' => [
878 'map_group' => 'special',
879 'mode' => XMPReader::MODE_SIMPLE,
880 ],
881 ],
882 /* Note, in iptc schemas, the legacy properties are denoted
883 * as deprecated, since other properties should used instead,
884 * and properties marked as deprecated in the standard are
885 * are marked as general here as they don't have replacements
886 */
887 'http://ns.adobe.com/photoshop/1.0/' => [
888 'City' => [
889 'map_group' => 'deprecated',
890 'mode' => XMPReader::MODE_SIMPLE,
891 'map_name' => 'CityDest',
892 ],
893 'Country' => [
894 'map_group' => 'deprecated',
895 'mode' => XMPReader::MODE_SIMPLE,
896 'map_name' => 'CountryDest',
897 ],
898 'State' => [
899 'map_group' => 'deprecated',
900 'mode' => XMPReader::MODE_SIMPLE,
901 'map_name' => 'ProvinceOrStateDest',
902 ],
903 'DateCreated' => [
904 'map_group' => 'deprecated',
905 // marking as deprecated as the xmp prop preferred
906 'mode' => XMPReader::MODE_SIMPLE,
907 'map_name' => 'DateTimeOriginal',
908 'validate' => 'validateDate',
909 // note this prop is an XMP, not IPTC date
910 ],
911 'CaptionWriter' => [
912 'map_group' => 'general',
913 'mode' => XMPReader::MODE_SIMPLE,
914 'map_name' => 'Writer',
915 ],
916 'Instructions' => [
917 'map_group' => 'general',
918 'mode' => XMPReader::MODE_SIMPLE,
919 'map_name' => 'SpecialInstructions',
920 ],
921 'TransmissionReference' => [
922 'map_group' => 'general',
923 'mode' => XMPReader::MODE_SIMPLE,
924 'map_name' => 'OriginalTransmissionRef',
925 ],
926 'AuthorsPosition' => [
927 /* This corresponds with 2:85
928 * By-line Title, which needs to be
929 * handled weirdly to correspond
930 * with iptc/exif. */
931 'map_group' => 'special',
932 'mode' => XMPReader::MODE_SIMPLE
933 ],
934 'Credit' => [
935 'map_group' => 'general',
936 'mode' => XMPReader::MODE_SIMPLE,
937 ],
938 'Source' => [
939 'map_group' => 'general',
940 'mode' => XMPReader::MODE_SIMPLE,
941 ],
942 'Urgency' => [
943 'map_group' => 'general',
944 'mode' => XMPReader::MODE_SIMPLE,
945 ],
946 'Category' => [
947 // Note, this prop is deprecated, but in general
948 // group since it doesn't have a replacement.
949 'map_group' => 'general',
950 'mode' => XMPReader::MODE_SIMPLE,
951 'map_name' => 'iimCategory',
952 ],
953 'SupplementalCategories' => [
954 'map_group' => 'general',
955 'mode' => XMPReader::MODE_BAG,
956 'map_name' => 'iimSupplementalCategory',
957 ],
958 'Headline' => [
959 'map_group' => 'general',
960 'mode' => XMPReader::MODE_SIMPLE
961 ],
962 ],
963 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/' => [
964 'CountryCode' => [
965 'map_group' => 'deprecated',
966 'mode' => XMPReader::MODE_SIMPLE,
967 'map_name' => 'CountryCodeDest',
968 ],
969 'IntellectualGenre' => [
970 'map_group' => 'general',
971 'mode' => XMPReader::MODE_SIMPLE,
972 ],
973 // Note, this is a six digit code.
974 // See: http://cv.iptc.org/newscodes/scene/
975 // Since these aren't really all that common,
976 // we just show the number.
977 'Scene' => [
978 'map_group' => 'general',
979 'mode' => XMPReader::MODE_BAG,
980 'validate' => 'validateInteger',
981 'map_name' => 'SceneCode',
982 ],
983 /* Note: SubjectCode should be an 8 ascii digits.
984 * it is not really an integer (has leading 0's,
985 * cannot have a +/- sign), but validateInteger
986 * will let it through.
987 */
988 'SubjectCode' => [
989 'map_group' => 'general',
990 'mode' => XMPReader::MODE_BAG,
991 'map_name' => 'SubjectNewsCode',
992 'validate' => 'validateInteger'
993 ],
994 'Location' => [
995 'map_group' => 'deprecated',
996 'mode' => XMPReader::MODE_SIMPLE,
997 'map_name' => 'SublocationDest',
998 ],
999 'CreatorContactInfo' => [
1000 /* Note this maps to 2:118 in iim
1001 * (Contact) field. However those field
1002 * types are slightly different - 2:118
1003 * is free form text field, where this
1004 * is more structured.
1005 */
1006 'map_group' => 'general',
1007 'mode' => XMPReader::MODE_STRUCT,
1008 'map_name' => 'Contact',
1009 'children' => [
1010 'CiAdrExtadr' => true,
1011 'CiAdrCity' => true,
1012 'CiAdrCtry' => true,
1013 'CiEmailWork' => true,
1014 'CiTelWork' => true,
1015 'CiAdrPcode' => true,
1016 'CiAdrRegion' => true,
1017 'CiUrlWork' => true,
1018 ],
1019 ],
1020 'CiAdrExtadr' => [ /* address */
1021 'map_group' => 'general',
1022 'mode' => XMPReader::MODE_SIMPLE,
1023 'structPart' => true,
1024 ],
1025 'CiAdrCity' => [ /* city */
1026 'map_group' => 'general',
1027 'mode' => XMPReader::MODE_SIMPLE,
1028 'structPart' => true,
1029 ],
1030 'CiAdrCtry' => [ /* country */
1031 'map_group' => 'general',
1032 'mode' => XMPReader::MODE_SIMPLE,
1033 'structPart' => true,
1034 ],
1035 'CiEmailWork' => [ /* email (possibly separated by ',') */
1036 'map_group' => 'general',
1037 'mode' => XMPReader::MODE_SIMPLE,
1038 'structPart' => true,
1039 ],
1040 'CiTelWork' => [ /* telephone */
1041 'map_group' => 'general',
1042 'mode' => XMPReader::MODE_SIMPLE,
1043 'structPart' => true,
1044 ],
1045 'CiAdrPcode' => [ /* postal code */
1046 'map_group' => 'general',
1047 'mode' => XMPReader::MODE_SIMPLE,
1048 'structPart' => true,
1049 ],
1050 'CiAdrRegion' => [ /* province/state */
1051 'map_group' => 'general',
1052 'mode' => XMPReader::MODE_SIMPLE,
1053 'structPart' => true,
1054 ],
1055 'CiUrlWork' => [ /* url. Multiple may be separated by comma. */
1056 'map_group' => 'general',
1057 'mode' => XMPReader::MODE_SIMPLE,
1058 'structPart' => true,
1059 ],
1060 /* End contact info struct properties */
1061 ],
1062 'http://iptc.org/std/Iptc4xmpExt/2008-02-29/' => [
1063 'Event' => [
1064 'map_group' => 'general',
1065 'mode' => XMPReader::MODE_SIMPLE,
1066 ],
1067 'OrganisationInImageName' => [
1068 'map_group' => 'general',
1069 'mode' => XMPReader::MODE_BAG,
1070 'map_name' => 'OrganisationInImage'
1071 ],
1072 'PersonInImage' => [
1073 'map_group' => 'general',
1074 'mode' => XMPReader::MODE_BAG,
1075 ],
1076 'MaxAvailHeight' => [
1077 'map_group' => 'general',
1078 'mode' => XMPReader::MODE_SIMPLE,
1079 'validate' => 'validateInteger',
1080 'map_name' => 'OriginalImageHeight',
1081 ],
1082 'MaxAvailWidth' => [
1083 'map_group' => 'general',
1084 'mode' => XMPReader::MODE_SIMPLE,
1085 'validate' => 'validateInteger',
1086 'map_name' => 'OriginalImageWidth',
1087 ],
1088 // LocationShown and LocationCreated are handled
1089 // specially because they are hierarchical, but we
1090 // also want to merge with the old non-hierarchical.
1091 'LocationShown' => [
1092 'map_group' => 'special',
1093 'mode' => XMPReader::MODE_BAGSTRUCT,
1094 'children' => [
1095 'WorldRegion' => true,
1096 'CountryCode' => true, /* iso code */
1097 'CountryName' => true,
1098 'ProvinceState' => true,
1099 'City' => true,
1100 'Sublocation' => true,
1101 ],
1102 ],
1103 'LocationCreated' => [
1104 'map_group' => 'special',
1105 'mode' => XMPReader::MODE_BAGSTRUCT,
1106 'children' => [
1107 'WorldRegion' => true,
1108 'CountryCode' => true, /* iso code */
1109 'CountryName' => true,
1110 'ProvinceState' => true,
1111 'City' => true,
1112 'Sublocation' => true,
1113 ],
1114 ],
1115 'WorldRegion' => [
1116 'map_group' => 'special',
1117 'mode' => XMPReader::MODE_SIMPLE,
1118 'structPart' => true,
1119 ],
1120 'CountryCode' => [
1121 'map_group' => 'special',
1122 'mode' => XMPReader::MODE_SIMPLE,
1123 'structPart' => true,
1124 ],
1125 'CountryName' => [
1126 'map_group' => 'special',
1127 'mode' => XMPReader::MODE_SIMPLE,
1128 'structPart' => true,
1129 'map_name' => 'Country',
1130 ],
1131 'ProvinceState' => [
1132 'map_group' => 'special',
1133 'mode' => XMPReader::MODE_SIMPLE,
1134 'structPart' => true,
1135 'map_name' => 'ProvinceOrState',
1136 ],
1137 'City' => [
1138 'map_group' => 'special',
1139 'mode' => XMPReader::MODE_SIMPLE,
1140 'structPart' => true,
1141 ],
1142 'Sublocation' => [
1143 'map_group' => 'special',
1144 'mode' => XMPReader::MODE_SIMPLE,
1145 'structPart' => true,
1146 ],
1147
1148 /* Other props that might be interesting but
1149 * Not currently extracted:
1150 * ArtworkOrObject, (info about objects in picture)
1151 * DigitalSourceType
1152 * RegistryId
1153 */
1154 ],
1155
1156 /* Plus props we might want to consider:
1157 * (Note: some of these have unclear/incomplete definitions
1158 * from the iptc4xmp standard).
1159 * ImageSupplier (kind of like iptc source field)
1160 * ImageSupplierId (id code for image from supplier)
1161 * CopyrightOwner
1162 * ImageCreator
1163 * Licensor
1164 * Various model release fields
1165 * Property release fields.
1166 */
1167 ];
1168 }