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