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