Merge to trunk everything in img_metadata branch.
[lhc/web/wiklou.git] / includes / media / Jpeg.php
1 <?php
2 /**
3 * @file
4 * @ingroup Media
5 */
6
7 /** JPEG specific handler.
8 * Inherits most stuff from BitmapHandler, just here to do the metadata handler differently
9 * @ingroup Media
10 */
11 class JpegHandler extends BitmapHandler {
12
13 const BROKEN_FILE = '-1'; // error extracting metadata
14 const OLD_BROKEN_FILE = '0'; // outdated error extracting metadata.
15
16 function getMetadata ( $image, $filename ) {
17 try {
18 $meta = BitmapMetadataHandler::Jpeg( $filename );
19 if ( !is_array( $meta ) ) {
20 // This should never happen, but doesn't hurt to be paranoid.
21 throw new MWException('Metadata array is not an array');
22 }
23 $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
24 return serialize( $meta );
25 }
26 catch ( MWException $e ) {
27 // BitmapMetadataHandler throws an exception in certain exceptional cases like if file does not exist.
28 wfDebug( __METHOD__ . ': ' . $e->getMessage() . "\n" );
29
30 /* This used to use 0 (self::OLD_BROKEN_FILE) for the cases
31 * * No metadata in the file
32 * * Something is broken in the file.
33 * However, if the metadata support gets expanded then you can't tell if the 0 is from
34 * a broken file, or just no props found. A broken file is likely to stay broken, but
35 * a file which had no props could have props once the metadata support is improved.
36 * Thus switch to using -1 to denote only a broken file, and use an array with only
37 * MEDIAWIKI_EXIF_VERSION to denote no props.
38 */
39 return self::BROKEN_FILE;
40 }
41 }
42
43 function convertMetadataVersion( $metadata, $version = 1 ) {
44 // basically flattens arrays.
45 $version = explode(';', $version, 2);
46 $version = intval($version[0]);
47 if ( $version < 1 || $version >= 2 ) {
48 return $metadata;
49 }
50
51 $avoidHtml = true;
52
53 if ( !is_array( $metadata ) ) {
54 $metadata = unserialize( $metadata );
55 }
56 if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] != 2 ) {
57 return $metadata;
58 }
59
60 // Treat Software as a special case because in can contain
61 // an array of (SoftwareName, Version).
62 if (isset( $metadata['Software'] )
63 && is_array( $metadata['Software'] )
64 && is_array( $metadata['Software'][0])
65 && isset( $metadata['Software'][0][0] )
66 && isset( $metadata['Software'][0][1])
67 ) {
68 $metadata['Software'] = $metadata['Software'][0][0] . ' (Version '
69 . $metadata['Software'][0][1] . ')';
70 }
71
72 // ContactInfo also has to be dealt with specially
73 if ( isset( $metadata['Contact'] ) ) {
74 $metadata['Contact'] =
75 FormatMetadata::collapseContactInfo(
76 $metadata['Contact'] );
77 }
78
79 foreach ( $metadata as &$val ) {
80 if ( is_array( $val ) ) {
81 $val = FormatMetadata::flattenArray( $val, 'ul', $avoidHtml );
82 }
83 }
84 $metadata['MEDIAWIKI_EXIF_VERSION'] = 1;
85 return $metadata;
86 }
87
88 function isMetadataValid( $image, $metadata ) {
89 global $wgShowEXIF;
90 if ( !$wgShowEXIF ) {
91 # Metadata disabled and so an empty field is expected
92 return self::METADATA_GOOD;
93 }
94 if ( $metadata === self::OLD_BROKEN_FILE ) {
95 # Old special value indicating that there is no EXIF data in the file.
96 # or that there was an error well extracting the metadata.
97 wfDebug( __METHOD__ . ": back-compat version\n");
98 return self::METADATA_COMPATIBLE;
99 }
100 if ( $metadata === self::BROKEN_FILE ) {
101 return self::METADATA_GOOD;
102 }
103 wfSuppressWarnings();
104 $exif = unserialize( $metadata );
105 wfRestoreWarnings();
106 if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) ||
107 $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version() )
108 {
109 if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) &&
110 $exif['MEDIAWIKI_EXIF_VERSION'] == 1 )
111 {
112 //back-compatible but old
113 wfDebug( __METHOD__.": back-compat version\n" );
114 return self::METADATA_COMPATIBLE;
115 }
116 # Wrong (non-compatible) version
117 wfDebug( __METHOD__.": wrong version\n" );
118 return self::METADATA_BAD;
119 }
120 return self::METADATA_GOOD;
121 }
122
123 function formatMetadata( $image ) {
124 $metadata = $image->getMetadata();
125 if ( !$metadata || $metadata == self::BROKEN_FILE ) {
126 return false;
127 }
128 $exif = unserialize( $metadata );
129 if ( !$exif ) {
130 return false;
131 }
132 unset( $exif['MEDIAWIKI_EXIF_VERSION'] );
133 if ( count( $exif ) == 0 ) {
134 return false;
135 }
136 return $this->formatMetadataHelper( $exif );
137 }
138
139
140 }