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