1d580ff7f36984fb94e53514137bc754e73a48ea
[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 /**** Do not extract this property
561 * It interferes with auto exif rotation.
562 * 'Orientation' => array(
563 * 'map_group' => 'exif',
564 * 'mode' => XMPReader::MODE_SIMPLE,
565 * 'validate' => 'validateClosed',
566 * 'choices' => array( '1' => true, '2' => true, '3' => true, '4' => true, 5 => true,
567 * '6' => true, '7' => true, '8' => true ),
568 *),
569 ******/
570 'PhotometricInterpretation' => array(
571 'map_group' => 'exif',
572 'mode' => XMPReader::MODE_SIMPLE,
573 'validate' => 'validateClosed',
574 'choices' => array( '2' => true, '6' => true ),
575 ),
576 'PlanerConfiguration' => array(
577 'map_group' => 'exif',
578 'mode' => XMPReader::MODE_SIMPLE,
579 'validate' => 'validateClosed',
580 'choices' => array( '1' => true, '2' => true ),
581 ),
582 'PrimaryChromaticities' => array(
583 'map_group' => 'exif',
584 'mode' => XMPReader::MODE_SEQ,
585 'validate' => 'validateRational',
586 ),
587 'ReferenceBlackWhite' => array(
588 'map_group' => 'exif',
589 'mode' => XMPReader::MODE_SEQ,
590 'validate' => 'validateRational',
591 ),
592 'ResolutionUnit' => array(
593 'map_group' => 'exif',
594 'mode' => XMPReader::MODE_SIMPLE,
595 'validate' => 'validateClosed',
596 'choices' => array( '2' => true, '3' => true ),
597 ),
598 'SamplesPerPixel' => array(
599 'map_group' => 'exif',
600 'mode' => XMPReader::MODE_SIMPLE,
601 'validate' => 'validateInteger',
602 ),
603 'Software' => array( /* see xmp:CreatorTool */
604 'map_group' => 'exif',
605 'mode' => XMPReader::MODE_SIMPLE,
606 ),
607 /* ignore TransferFunction */
608 'WhitePoint' => array(
609 'map_group' => 'exif',
610 'mode' => XMPReader::MODE_SEQ,
611 'validate' => 'validateRational',
612 ),
613 'XResolution' => array(
614 'map_group' => 'exif',
615 'mode' => XMPReader::MODE_SIMPLE,
616 'validate' => 'validateRational',
617 ),
618 'YResolution' => array(
619 'map_group' => 'exif',
620 'mode' => XMPReader::MODE_SIMPLE,
621 'validate' => 'validateRational',
622 ),
623 'YCbCrCoefficients' => array(
624 'map_group' => 'exif',
625 'mode' => XMPReader::MODE_SEQ,
626 'validate' => 'validateRational',
627 ),
628 'YCbCrPositioning' => array(
629 'map_group' => 'exif',
630 'mode' => XMPReader::MODE_SIMPLE,
631 'validate' => 'validateClosed',
632 'choices' => array( '1' => true, '2' => true ),
633 ),
634 'YCbCrSubSampling' => array(
635 'map_group' => 'exif',
636 'mode' => XMPReader::MODE_SEQ,
637 'validate' => 'validateClosed',
638 'choices' => array( '1' => true, '2' => true ),
639 ),
640 ),
641 'http://ns.adobe.com/exif/1.0/aux/' => array(
642 'Lens' => array(
643 'map_group' => 'exif',
644 'mode' => XMPReader::MODE_SIMPLE,
645 ),
646 'SerialNumber' => array(
647 'map_group' => 'exif',
648 'mode' => XMPReader::MODE_SIMPLE,
649 ),
650 'OwnerName' => array(
651 'map_group' => 'exif',
652 'map_name' => 'CameraOwnerName',
653 'mode' => XMPReader::MODE_SIMPLE,
654 ),
655 ),
656 'http://purl.org/dc/elements/1.1/' => array(
657 'title' => array(
658 'map_group' => 'general',
659 'map_name' => 'ObjectName',
660 'mode' => XMPReader::MODE_LANG
661 ),
662 'description' => array(
663 'map_group' => 'general',
664 'map_name' => 'ImageDescription',
665 'mode' => XMPReader::MODE_LANG
666 ),
667 'contributor' => array(
668 'map_group' => 'general',
669 'map_name' => 'dc-contributor',
670 'mode' => XMPReader::MODE_BAG
671 ),
672 'coverage' => array(
673 'map_group' => 'general',
674 'map_name' => 'dc-coverage',
675 'mode' => XMPReader::MODE_SIMPLE,
676 ),
677 'creator' => array(
678 'map_group' => 'general',
679 'map_name' => 'Artist', //map with exif Artist, iptc byline (2:80)
680 'mode' => XMPReader::MODE_SEQ,
681 ),
682 'date' => array(
683 'map_group' => 'general',
684 // Note, not mapped with other date properties, as this type of date is
685 // non-specific: "A point or period of time associated with an event in
686 // the lifecycle of the resource"
687 'map_name' => 'dc-date',
688 'mode' => XMPReader::MODE_SEQ,
689 'validate' => 'validateDate',
690 ),
691 /* Do not extract dc:format, as we've got better ways to determine mimetype */
692 'identifier' => array(
693 'map_group' => 'deprecated',
694 'map_name' => 'Identifier',
695 'mode' => XMPReader::MODE_SIMPLE,
696 ),
697 'language' => array(
698 'map_group' => 'general',
699 'map_name' => 'LanguageCode', /* mapped with iptc 2:135 */
700 'mode' => XMPReader::MODE_BAG,
701 'validate' => 'validateLangCode',
702 ),
703 'publisher' => array(
704 'map_group' => 'general',
705 'map_name' => 'dc-publisher',
706 'mode' => XMPReader::MODE_BAG,
707 ),
708 // for related images/resources
709 'relation' => array(
710 'map_group' => 'general',
711 'map_name' => 'dc-relation',
712 'mode' => XMPReader::MODE_BAG,
713 ),
714 'rights' => array(
715 'map_group' => 'general',
716 'map_name' => 'Copyright',
717 'mode' => XMPReader::MODE_LANG,
718 ),
719 // Note: source is not mapped with iptc source, since iptc
720 // source describes the source of the image in terms of a person
721 // who provided the image, where this is to describe an image that the
722 // current one is based on.
723 'source' => array(
724 'map_group' => 'general',
725 'map_name' => 'dc-source',
726 'mode' => XMPReader::MODE_SIMPLE,
727 ),
728 'subject' => array(
729 'map_group' => 'general',
730 'map_name' => 'Keywords', /* maps to iptc 2:25 */
731 'mode' => XMPReader::MODE_BAG,
732 ),
733 'type' => array(
734 'map_group' => 'general',
735 'map_name' => 'dc-type',
736 'mode' => XMPReader::MODE_BAG,
737 ),
738 ),
739 'http://ns.adobe.com/xap/1.0/' => array(
740 'CreateDate' => array(
741 'map_group' => 'general',
742 'map_name' => 'DateTimeDigitized',
743 'mode' => XMPReader::MODE_SIMPLE,
744 'validate' => 'validateDate',
745 ),
746 'CreatorTool' => array(
747 'map_group' => 'general',
748 'map_name' => 'Software',
749 'mode' => XMPReader::MODE_SIMPLE
750 ),
751 'Identifier' => array(
752 'map_group' => 'general',
753 'mode' => XMPReader::MODE_BAG,
754 ),
755 'Label' => array(
756 'map_group' => 'general',
757 'mode' => XMPReader::MODE_SIMPLE,
758 ),
759 'ModifyDate' => array(
760 'map_group' => 'general',
761 'mode' => XMPReader::MODE_SIMPLE,
762 'map_name' => 'DateTime',
763 'validate' => 'validateDate',
764 ),
765 'MetadataDate' => array(
766 'map_group' => 'general',
767 'mode' => XMPReader::MODE_SIMPLE,
768 // map_name to be consistent with other date names.
769 'map_name' => 'DateTimeMetadata',
770 'validate' => 'validateDate',
771 ),
772 'Nickname' => array(
773 'map_group' => 'general',
774 'mode' => XMPReader::MODE_SIMPLE,
775 ),
776 'Rating' => array(
777 'map_group' => 'general',
778 'mode' => XMPReader::MODE_SIMPLE,
779 'validate' => 'validateRating',
780 ),
781 ),
782 'http://ns.adobe.com/xap/1.0/rights/' => array(
783 'Certificate' => array(
784 'map_group' => 'general',
785 'map_name' => 'RightsCertificate',
786 'mode' => XMPReader::MODE_SIMPLE,
787 ),
788 'Marked' => array(
789 'map_group' => 'general',
790 'map_name' => 'Copyrighted',
791 'mode' => XMPReader::MODE_SIMPLE,
792 'validate' => 'validateBoolean',
793 ),
794 'Owner' => array(
795 'map_group' => 'general',
796 'map_name' => 'CopyrightOwner',
797 'mode' => XMPReader::MODE_BAG,
798 ),
799 // this seems similar to dc:rights.
800 'UsageTerms' => array(
801 'map_group' => 'general',
802 'mode' => XMPReader::MODE_LANG,
803 ),
804 'WebStatement' => array(
805 'map_group' => 'general',
806 'mode' => XMPReader::MODE_SIMPLE,
807 ),
808 ),
809 // XMP media management.
810 'http://ns.adobe.com/xap/1.0/mm/' => array(
811 // if we extract the exif UniqueImageID, might
812 // as well do this too.
813 'OriginalDocumentID' => array(
814 'map_group' => 'general',
815 'mode' => XMPReader::MODE_SIMPLE,
816 ),
817 // It might also be useful to do xmpMM:LastURL
818 // and xmpMM:DerivedFrom as you can potentially,
819 // get the url of this document/source for this
820 // document. However whats more likely is you'd
821 // get a file:// url for the path of the doc,
822 // which is somewhat of a privacy issue.
823 ),
824 'http://creativecommons.org/ns#' => array(
825 'license' => array(
826 'map_name' => 'LicenseUrl',
827 'map_group' => 'general',
828 'mode' => XMPReader::MODE_SIMPLE,
829 ),
830 'morePermissions' => array(
831 'map_name' => 'MorePermissionsUrl',
832 'map_group' => 'general',
833 'mode' => XMPReader::MODE_SIMPLE,
834 ),
835 'attributionURL' => array(
836 'map_group' => 'general',
837 'map_name' => 'AttributionUrl',
838 'mode' => XMPReader::MODE_SIMPLE,
839 ),
840 'attributionName' => array(
841 'map_group' => 'general',
842 'map_name' => 'PreferredAttributionName',
843 'mode' => XMPReader::MODE_SIMPLE,
844 ),
845 ),
846 //Note, this property affects how jpeg metadata is extracted.
847 'http://ns.adobe.com/xmp/note/' => array(
848 'HasExtendedXMP' => array(
849 'map_group' => 'special',
850 'mode' => XMPReader::MODE_SIMPLE,
851 ),
852 ),
853 /* Note, in iptc schemas, the legacy properties are denoted
854 * as deprecated, since other properties should used instead,
855 * and properties marked as deprecated in the standard are
856 * are marked as general here as they don't have replacements
857 */
858 'http://ns.adobe.com/photoshop/1.0/' => array(
859 'City' => array(
860 'map_group' => 'deprecated',
861 'mode' => XMPReader::MODE_SIMPLE,
862 'map_name' => 'CityDest',
863 ),
864 'Country' => array(
865 'map_group' => 'deprecated',
866 'mode' => XMPReader::MODE_SIMPLE,
867 'map_name' => 'CountryDest',
868 ),
869 'State' => array(
870 'map_group' => 'deprecated',
871 'mode' => XMPReader::MODE_SIMPLE,
872 'map_name' => 'ProvinceOrStateDest',
873 ),
874 'DateCreated' => array(
875 'map_group' => 'deprecated',
876 // marking as deprecated as the xmp prop preferred
877 'mode' => XMPReader::MODE_SIMPLE,
878 'map_name' => 'DateTimeOriginal',
879 'validate' => 'validateDate',
880 // note this prop is an XMP, not IPTC date
881 ),
882 'CaptionWriter' => array(
883 'map_group' => 'general',
884 'mode' => XMPReader::MODE_SIMPLE,
885 'map_name' => 'Writer',
886 ),
887 'Instructions' => array(
888 'map_group' => 'general',
889 'mode' => XMPReader::MODE_SIMPLE,
890 'map_name' => 'SpecialInstructions',
891 ),
892 'TransmissionReference' => array(
893 'map_group' => 'general',
894 'mode' => XMPReader::MODE_SIMPLE,
895 'map_name' => 'OriginalTransmissionRef',
896 ),
897 'AuthorsPosition' => array(
898 /* This corresponds with 2:85
899 * By-line Title, which needs to be
900 * handled weirdly to correspond
901 * with iptc/exif. */
902 'map_group' => 'special',
903 'mode' => XMPReader::MODE_SIMPLE
904 ),
905 'Credit' => array(
906 'map_group' => 'general',
907 'mode' => XMPReader::MODE_SIMPLE,
908 ),
909 'Source' => array(
910 'map_group' => 'general',
911 'mode' => XMPReader::MODE_SIMPLE,
912 ),
913 'Urgency' => array(
914 'map_group' => 'general',
915 'mode' => XMPReader::MODE_SIMPLE,
916 ),
917 'Category' => array(
918 // Note, this prop is deprecated, but in general
919 // group since it doesn't have a replacement.
920 'map_group' => 'general',
921 'mode' => XMPReader::MODE_SIMPLE,
922 'map_name' => 'iimCategory',
923 ),
924 'SupplementalCategories' => array(
925 'map_group' => 'general',
926 'mode' => XMPReader::MODE_BAG,
927 'map_name' => 'iimSupplementalCategory',
928 ),
929 'Headline' => array(
930 'map_group' => 'general',
931 'mode' => XMPReader::MODE_SIMPLE
932 ),
933 ),
934 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/' => array(
935 'CountryCode' => array(
936 'map_group' => 'deprecated',
937 'mode' => XMPReader::MODE_SIMPLE,
938 'map_name' => 'CountryCodeDest',
939 ),
940 'IntellectualGenre' => array(
941 'map_group' => 'general',
942 'mode' => XMPReader::MODE_SIMPLE,
943 ),
944 // Note, this is a six digit code.
945 // See: http://cv.iptc.org/newscodes/scene/
946 // Since these aren't really all that common,
947 // we just show the number.
948 'Scene' => array(
949 'map_group' => 'general',
950 'mode' => XMPReader::MODE_BAG,
951 'validate' => 'validateInteger',
952 'map_name' => 'SceneCode',
953 ),
954 /* Note: SubjectCode should be an 8 ascii digits.
955 * it is not really an integer (has leading 0's,
956 * cannot have a +/- sign), but validateInteger
957 * will let it through.
958 */
959 'SubjectCode' => array(
960 'map_group' => 'general',
961 'mode' => XMPReader::MODE_BAG,
962 'map_name' => 'SubjectNewsCode',
963 'validate' => 'validateInteger'
964 ),
965 'Location' => array(
966 'map_group' => 'deprecated',
967 'mode' => XMPReader::MODE_SIMPLE,
968 'map_name' => 'SublocationDest',
969 ),
970 'CreatorContactInfo' => array(
971 /* Note this maps to 2:118 in iim
972 * (Contact) field. However those field
973 * types are slightly different - 2:118
974 * is free form text field, where this
975 * is more structured.
976 */
977 'map_group' => 'general',
978 'mode' => XMPReader::MODE_STRUCT,
979 'map_name' => 'Contact',
980 'children' => array(
981 'CiAdrExtadr' => true,
982 'CiAdrCity' => true,
983 'CiAdrCtry' => true,
984 'CiEmailWork' => true,
985 'CiTelWork' => true,
986 'CiAdrPcode' => true,
987 'CiAdrRegion' => true,
988 'CiUrlWork' => true,
989 ),
990 ),
991 'CiAdrExtadr' => array( /* address */
992 'map_group' => 'general',
993 'mode' => XMPReader::MODE_SIMPLE,
994 'structPart'=> true,
995 ),
996 'CiAdrCity' => array( /* city */
997 'map_group' => 'general',
998 'mode' => XMPReader::MODE_SIMPLE,
999 'structPart'=> true,
1000 ),
1001 'CiAdrCtry' => array( /* country */
1002 'map_group' => 'general',
1003 'mode' => XMPReader::MODE_SIMPLE,
1004 'structPart'=> true,
1005 ),
1006 'CiEmailWork' => array( /* email (possibly separated by ',') */
1007 'map_group' => 'general',
1008 'mode' => XMPReader::MODE_SIMPLE,
1009 'structPart'=> true,
1010 ),
1011 'CiTelWork' => array( /* telephone */
1012 'map_group' => 'general',
1013 'mode' => XMPReader::MODE_SIMPLE,
1014 'structPart'=> true,
1015 ),
1016 'CiAdrPcode' => array( /* postal code */
1017 'map_group' => 'general',
1018 'mode' => XMPReader::MODE_SIMPLE,
1019 'structPart'=> true,
1020 ),
1021 'CiAdrRegion' => array( /* province/state */
1022 'map_group' => 'general',
1023 'mode' => XMPReader::MODE_SIMPLE,
1024 'structPart'=> true,
1025 ),
1026 'CiUrlWork' => array( /* url. Multiple may be separated by comma. */
1027 'map_group' => 'general',
1028 'mode' => XMPReader::MODE_SIMPLE,
1029 'structPart'=> true,
1030 ),
1031 /* End contact info struct properties */
1032 ),
1033 'http://iptc.org/std/Iptc4xmpExt/2008-02-29/' => array(
1034 'Event' => array(
1035 'map_group' => 'general',
1036 'mode' => XMPReader::MODE_SIMPLE,
1037 ),
1038 'OrganisationInImageName' => array(
1039 'map_group' => 'general',
1040 'mode' => XMPReader::MODE_BAG,
1041 'map_name' => 'OrganisationInImage'
1042 ),
1043 'PersonInImage' => array(
1044 'map_group' => 'general',
1045 'mode' => XMPReader::MODE_BAG,
1046 ),
1047 'MaxAvailHeight' => array(
1048 'map_group' => 'general',
1049 'mode' => XMPReader::MODE_SIMPLE,
1050 'validate' => 'validateInteger',
1051 'map_name' => 'OriginalImageHeight',
1052 ),
1053 'MaxAvailWidth' => array(
1054 'map_group' => 'general',
1055 'mode' => XMPReader::MODE_SIMPLE,
1056 'validate' => 'validateInteger',
1057 'map_name' => 'OriginalImageWidth',
1058 ),
1059 // LocationShown and LocationCreated are handled
1060 // specially because they are hierarchical, but we
1061 // also want to merge with the old non-hierarchical.
1062 'LocationShown' => array(
1063 'map_group' => 'special',
1064 'mode' => XMPReader::MODE_BAGSTRUCT,
1065 'children' => array(
1066 'WorldRegion' => true,
1067 'CountryCode' => true, /* iso code */
1068 'CountryName' => true,
1069 'ProvinceState' => true,
1070 'City' => true,
1071 'Sublocation' => true,
1072 ),
1073 ),
1074 'LocationCreated' => array(
1075 'map_group' => 'special',
1076 'mode' => XMPReader::MODE_BAGSTRUCT,
1077 'children' => array(
1078 'WorldRegion' => true,
1079 'CountryCode' => true, /* iso code */
1080 'CountryName' => true,
1081 'ProvinceState' => true,
1082 'City' => true,
1083 'Sublocation' => true,
1084 ),
1085 ),
1086 'WorldRegion' => array(
1087 'map_group' => 'special',
1088 'mode' => XMPReader::MODE_SIMPLE,
1089 'structPart'=> true,
1090 ),
1091 'CountryCode' => array(
1092 'map_group' => 'special',
1093 'mode' => XMPReader::MODE_SIMPLE,
1094 'structPart'=> true,
1095 ),
1096 'CountryName' => array(
1097 'map_group' => 'special',
1098 'mode' => XMPReader::MODE_SIMPLE,
1099 'structPart'=> true,
1100 'map_name' => 'Country',
1101 ),
1102 'ProvinceState' => array(
1103 'map_group' => 'special',
1104 'mode' => XMPReader::MODE_SIMPLE,
1105 'structPart'=> true,
1106 'map_name' => 'ProvinceOrState',
1107 ),
1108 'City' => array(
1109 'map_group' => 'special',
1110 'mode' => XMPReader::MODE_SIMPLE,
1111 'structPart'=> true,
1112 ),
1113 'Sublocation' => array(
1114 'map_group' => 'special',
1115 'mode' => XMPReader::MODE_SIMPLE,
1116 'structPart'=> true,
1117 ),
1118
1119 /* Other props that might be interesting but
1120 * Not currently extracted:
1121 * ArtworkOrObject, (info about objects in picture)
1122 * DigitalSourceType
1123 * RegistryId
1124 */
1125 ),
1126
1127 /* Plus props we might want to consider:
1128 * (Note: some of these have unclear/incomplete definitions
1129 * from the iptc4xmp standard).
1130 * ImageSupplier (kind of like iptc source field)
1131 * ImageSupplierId (id code for image from supplier)
1132 * CopyrightOwner
1133 * ImageCreator
1134 * Licensor
1135 * Various model release fields
1136 * Property release fields.
1137 */
1138 );
1139 }