24 use Wikimedia\AtEase\AtEase;
42 public static function parse( $rawData ) {
43 $parsed = iptcparse( $rawData );
45 if ( !is_array( $parsed ) ) {
51 if ( isset( $parsed[
'1#090'] ) && isset( $parsed[
'1#090'][0] ) ) {
59 unset( $parsed[
'1#090'] );
62 foreach ( $parsed as $tag => $val ) {
63 if ( isset( $val[0] ) && trim( $val[0] ) ==
'' ) {
64 wfDebugLog(
'iptc',
"IPTC tag $tag had only whitespace as its value." );
69 $data[
'ImageDescription'] = self::convIPTC( $val, $c );
72 $data[
'Copyright'] = self::convIPTC( $val, $c );
82 $bylines = self::convIPTC( $val, $c );
83 if ( isset( $parsed[
'2#085'] ) ) {
84 $titles = self::convIPTC( $parsed[
'2#085'], $c );
89 $titleCount = count( $titles );
90 for ( $i = 0; $i < $titleCount; $i++ ) {
91 if ( isset( $bylines[$i] ) ) {
94 $bylines[$i] = $titles[$i] .
', ' . $bylines[$i];
97 $data[
'Artist'] = $bylines;
100 $data[
'Keywords'] = self::convIPTC( $val, $c );
103 $data[
'CountryDest'] = self::convIPTC( $val, $c );
106 $data[
'ProvinceOrStateDest'] = self::convIPTC( $val, $c );
109 $data[
'CityDest'] = self::convIPTC( $val, $c );
112 $data[
'SublocationDest'] = self::convIPTC( $val, $c );
115 $data[
'ObjectName'] = self::convIPTC( $val, $c );
118 $data[
'SpecialInstructions'] = self::convIPTC( $val, $c );
121 $data[
'Headline'] = self::convIPTC( $val, $c );
126 $data[
'Credit'] = self::convIPTC( $val, $c );
132 $data[
'Source'] = self::convIPTC( $val, $c );
136 $data[
'EditStatus'] = self::convIPTC( $val, $c );
139 $data[
'iimCategory'] = self::convIPTC( $val, $c );
142 $data[
'iimSupplementalCategory'] = self::convIPTC( $val, $c );
145 $data[
'Urgency'] = self::convIPTC( $val, $c );
150 $data[
'FixtureIdentifier'] = self::convIPTC( $val, $c );
156 $data[
'LocationDestCode'] = self::convIPTC( $val, $c );
161 $data[
'LocationDest'] = self::convIPTC( $val, $c );
167 $software = self::convIPTC( $val, $c );
169 if ( count( $software ) !== 1 ) {
173 wfDebugLog(
'iptc',
'IPTC: Wrong count on 2:65 Software field' );
177 if ( isset( $parsed[
'2#070'] ) ) {
179 $softwareVersion = self::convIPTC( $parsed[
'2#070'], $c );
180 unset( $parsed[
'2#070'] );
181 $data[
'Software'] = [ [ $software[0], $softwareVersion[0] ] ];
183 $data[
'Software'] = $software;
189 $data[
'ObjectCycle'] = self::convIPTC( $val, $c );
197 $data[
'CountryCodeDest'] = self::convIPTC( $val, $c );
204 $data[
'OriginalTransmissionRef'] = self::convIPTC( $val, $c );
207 $data[
'Contact'] = self::convIPTC( $val, $c );
214 $data[
'Writer'] = self::convIPTC( $val, $c );
217 $data[
'LanguageCode'] = self::convIPTC( $val, $c );
227 $time = $parsed[
'2#060'] ?? [];
228 $timestamp = self::timeHelper( $val, $time, $c );
230 $data[
'DateTimeOriginal'] = $timestamp;
237 $time = $parsed[
'2#063'] ?? [];
238 $timestamp = self::timeHelper( $val, $time, $c );
240 $data[
'DateTimeDigitized'] = $timestamp;
246 $time = $parsed[
'2#035'] ?? [];
247 $timestamp = self::timeHelper( $val, $time, $c );
249 $data[
'DateTimeReleased'] = $timestamp;
255 $time = $parsed[
'2#038'] ?? [];
256 $timestamp = self::timeHelper( $val, $time, $c );
258 $data[
'DateTimeExpires'] = $timestamp;
266 if ( strlen( $val[0] ) === 2 ) {
268 $versionValue = ord( substr( $val[0], 0, 1 ) ) * 256;
269 $versionValue += ord( substr( $val[0], 1, 1 ) );
270 $data[
'iimVersion'] = $versionValue;
284 $con = self::convIPTC( $val, $c );
285 if ( strlen( $con[0] ) < 5 ) {
291 $extracted = substr( $con[0], 4 );
292 $data[
'IntellectualGenre'] = $extracted;
300 $codes = self::convIPTC( $val, $c );
301 foreach ( $codes as $ic ) {
302 $fields = explode(
':', $ic, 3 );
304 if ( count( $fields ) < 2 || $fields[0] !==
'IPTC' ) {
306 .
'Invalid 2:12 - ' . $ic );
309 $data[
'SubjectNewsCode'] = $fields[1];
328 wfDebugLog(
'iptc',
"Unsupported iptc tag: $tag. Value: " . implode(
',', $val ) );
345 private static function timeHelper( $date, $time, $charset ) {
346 if ( count( $date ) === 1 ) {
349 [ $date ] = self::convIPTC( $date, $charset );
354 if ( count( $time ) === 1 ) {
355 [ $time ] = self::convIPTC( $time, $charset );
358 $time =
'000000+0000';
362 if ( !( preg_match(
'/\d\d\d\d\d\d[-+]\d\d\d\d/', $time )
363 && preg_match(
'/\d\d\d\d\d\d\d\d/', $date )
364 && substr( $date, 0, 4 ) !==
'0000'
365 && substr( $date, 4, 2 ) !==
'00'
366 && substr( $date, 6, 2 ) !==
'00'
373 wfDebugLog(
'iptc',
"IPTC: invalid time ( $time ) or date ( $date )" );
378 $unixTS =
wfTimestamp( TS_UNIX, $date . substr( $time, 0, 6 ) );
379 if ( $unixTS ===
false ) {
380 wfDebugLog(
'iptc',
"IPTC: can't convert date to TS_UNIX: $date $time." );
385 $tz = ( (int)substr( $time, 7, 2 ) * 60 * 60 )
386 + ( (
int)substr( $time, 9, 2 ) * 60 );
388 if ( substr( $time, 6, 1 ) ===
'-' ) {
392 $finalTimestamp =
wfTimestamp( TS_EXIF, (
int)$unixTS + $tz );
393 if ( $finalTimestamp ===
false ) {
394 wfDebugLog(
'iptc',
"IPTC: can't make final timestamp. Date: " . ( (
int)$unixTS + $tz ) );
400 return substr( $finalTimestamp, 0, 10 );
402 return $finalTimestamp;
412 private static function convIPTC( $data, $charset ) {
413 if ( is_array( $data ) ) {
414 foreach ( $data as &$val ) {
415 $val = self::convIPTCHelper( $val, $charset );
418 $data = self::convIPTCHelper( $data, $charset );
431 private static function convIPTCHelper( $data, $charset ) {
433 AtEase::suppressWarnings();
434 $data = iconv( $charset,
"UTF-8//IGNORE", $data );
435 AtEase::restoreWarnings();
436 if ( $data ===
false ) {
438 wfDebugLog(
'iptc', __METHOD__ .
" Error converting iptc data charset $charset to utf-8" );
444 UtfNormal\Validator::quickIsNFCVerify( $data );
445 if ( $data === $oldData ) {
448 return self::convIPTCHelper( $oldData,
'Windows-1252' );
451 return trim( $data );
538 $c =
"CSA_Z243.4-1985-1";
541 $c =
"CSA_Z243.4-1985-2";
545 case "\x1b&@\x1b\$B":
546 case "\x1b&@\x1b\$(B":
547 $c =
"JIS_C6226-1983";
579 wfDebugLog(
'iptc', __METHOD__ .
': Unknown charset in iptc 1:90: ' . bin2hex( $tag ) );
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Class for some IPTC functions.
static parse( $rawData)
This takes the results of iptcparse() and puts it into a form that can be handled by mediawiki.
static getCharset( $tag)
take the value of 1:90 tag and returns a charset