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