Index: branches/img_metadata/phase3/maintenance/language/messages.inc |
— | — | @@ -2699,11 +2699,33 @@ |
2700 | 2700 | 'exif-gpsdatestamp', |
2701 | 2701 | 'exif-gpsdifferential', |
2702 | 2702 | 'exif-jpegfilecomment', |
| 2703 | + 'exif-keywords', |
| 2704 | + 'exif-countrydest', |
| 2705 | + 'exif-countrydestcode', |
| 2706 | + 'exif-provinceorstatedest', |
| 2707 | + 'exif-citydest', |
| 2708 | + 'exif-sublocationdest', |
| 2709 | + 'exif-objectname', |
| 2710 | + 'exif-specialinstructions', |
| 2711 | + 'exif-headline', |
| 2712 | + 'exif-credit', |
| 2713 | + 'exif-source', |
| 2714 | + 'exif-editstatus', |
| 2715 | + 'exif-urgency', |
| 2716 | + 'exif-fixtureidentifier', |
| 2717 | + 'exif-locationdest', |
| 2718 | + 'exif-locationdestcode', |
| 2719 | + 'exif-objectcycle', |
| 2720 | + 'exif-contact', |
| 2721 | + 'exif-writer', |
| 2722 | + 'exif-languagecode', |
| 2723 | + 'exif-iimversion', |
2703 | 2724 | ), |
2704 | 2725 | 'exif-values' => array( |
2705 | 2726 | 'exif-make-value', |
2706 | 2727 | 'exif-model-value', |
2707 | 2728 | 'exif-software-value', |
| 2729 | + 'exif-software-version-value', |
2708 | 2730 | ), |
2709 | 2731 | 'exif-compression' => array( |
2710 | 2732 | 'exif-compression-1', |
— | — | @@ -2901,6 +2923,11 @@ |
2902 | 2924 | 'exif-gpsdestdistance-m', |
2903 | 2925 | 'exif-gpsdestdistance-n', |
2904 | 2926 | ), |
| 2927 | + 'exif-objectcycle' => array( |
| 2928 | + 'exif-objectcycle-a', |
| 2929 | + 'exif-objectcycle-p', |
| 2930 | + 'exif-objectcycle-b', |
| 2931 | + ), |
2905 | 2932 | 'exif-gpsdirection' => array( |
2906 | 2933 | 'exif-gpsdirection-t', |
2907 | 2934 | 'exif-gpsdirection-m', |
Index: branches/img_metadata/phase3/maintenance/language/messageTypes.inc |
— | — | @@ -86,6 +86,7 @@ |
87 | 87 | 'exif-make-value', |
88 | 88 | 'exif-model-value', |
89 | 89 | 'exif-software-value', |
| 90 | + 'exif-software-version-value', |
90 | 91 | 'history_copyright', |
91 | 92 | 'licenses', |
92 | 93 | 'loginstart', |
— | — | @@ -600,4 +601,28 @@ |
601 | 602 | 'exif-gpsdirection-m', |
602 | 603 | //non-exif metadata that is still image metadata |
603 | 604 | 'exif-jpegfilecomment', |
| 605 | + 'exif-keywords', |
| 606 | + 'exif-countrydest', |
| 607 | + 'exif-countrydestcode', |
| 608 | + 'exif-stateorprovincedest', |
| 609 | + 'exif-citydest', |
| 610 | + 'exif-sublocationdest', |
| 611 | + 'exif-objectname', |
| 612 | + 'exif-specialinstructions', |
| 613 | + 'exif-headline', |
| 614 | + 'exif-credit', |
| 615 | + 'exif-source', |
| 616 | + 'exif-editstatus', |
| 617 | + 'exif-urgency', |
| 618 | + 'exif-fixtureidentifier', |
| 619 | + 'exif-locationdest', |
| 620 | + 'exif-locationdestcode', |
| 621 | + 'exif-objectcycle', |
| 622 | + 'exif-objectcycle-a', |
| 623 | + 'exif-objectcycle-p', |
| 624 | + 'exif-objectcycle-b', |
| 625 | + 'exif-contact', |
| 626 | + 'exif-writer', |
| 627 | + 'exif-languagecode', |
| 628 | + 'exif-iimversion', |
604 | 629 | ); |
Index: branches/img_metadata/phase3/includes/Exif.php |
— | — | @@ -1235,10 +1235,18 @@ |
1236 | 1236 | // the make, model and software name to link to their articles. |
1237 | 1237 | case 'Make': |
1238 | 1238 | case 'Model': |
1239 | | - case 'Software': |
1240 | 1239 | $val = $this->msg( $tag, '', $val ); |
1241 | 1240 | break; |
1242 | 1241 | |
| 1242 | + case 'Software': |
| 1243 | + if ( is_array( $val ) ) { |
| 1244 | + //if its a software, version array. |
| 1245 | + $val = wfMsg( 'exif-software-version-value', $val[0], $val[1] ); |
| 1246 | + } else { |
| 1247 | + $val = $this->msg( $tag, '', $val ); |
| 1248 | + } |
| 1249 | + break; |
| 1250 | + |
1243 | 1251 | case 'ExposureTime': |
1244 | 1252 | // Show the pretty fraction as well as decimal version |
1245 | 1253 | $val = wfMsg( 'exif-exposuretime-format', |
— | — | @@ -1262,13 +1270,48 @@ |
1263 | 1271 | case 'Artist': |
1264 | 1272 | case 'Copyright': |
1265 | 1273 | case 'GPSVersionID': |
| 1274 | + case 'Keywords': |
| 1275 | + case 'CountryDest': |
| 1276 | + case 'CountryDestCode': |
| 1277 | + case 'ProvinceOrStateDest': |
| 1278 | + case 'CityDest': |
| 1279 | + case 'SublocationDest': |
| 1280 | + case 'ObjectName': |
| 1281 | + case 'SpecialInstructions': |
| 1282 | + case 'Headline': |
| 1283 | + case 'Credit': |
| 1284 | + case 'Source': |
| 1285 | + case 'EditStatus': |
| 1286 | + case 'Urgency': |
| 1287 | + case 'FixtureIdentifier': |
| 1288 | + case 'LocationDest': |
| 1289 | + case 'LocationDestCode': |
| 1290 | + case 'Contact': |
| 1291 | + case 'Writer': |
| 1292 | + case 'JPEGFileComment': |
| 1293 | + |
1266 | 1294 | $val = htmlspecialchars( $val ); |
1267 | 1295 | break; |
1268 | 1296 | |
1269 | | - // Here begins the non-exif data |
1270 | | - case 'JPEGFileComment': |
1271 | | - $val = htmlspecialchars( $val ); |
| 1297 | + case 'ObjectCycle': |
| 1298 | + switch ( $val ) { |
| 1299 | + case 'a': case 'p': case 'b': |
| 1300 | + $val = $this->msg( $tag, $val ); |
| 1301 | + break; |
| 1302 | + default: |
| 1303 | + $val = htmlspecialchars( $val ); |
| 1304 | + break; |
| 1305 | + } |
1272 | 1306 | break; |
| 1307 | + |
| 1308 | + case 'LanguageCode': |
| 1309 | + $lang = $wgLang->getLanguageName( strtolower( $val ) ); |
| 1310 | + if ($lang) { |
| 1311 | + $val = htmlspecialchars( $lang ); |
| 1312 | + } else { |
| 1313 | + $val = htmlspecialchars( $val ); |
| 1314 | + } |
| 1315 | + break; |
1273 | 1316 | |
1274 | 1317 | default: |
1275 | 1318 | $val = $this->formatNum( $val ); |
Index: branches/img_metadata/phase3/includes/media/IPTC.php |
— | — | @@ -30,21 +30,155 @@ |
31 | 31 | //charset info contained in tag 1:90. |
32 | 32 | if (isset($parsed['1#090']) && isset($parsed['1#090'][0])) { |
33 | 33 | $c = self::getCharset($parsed['1#090'][0]); |
| 34 | + unset( $parsed['1#090'] ); |
34 | 35 | } |
35 | 36 | |
36 | 37 | foreach ( $parsed as $tag => $val ) { |
37 | 38 | switch( $tag ) { |
38 | | - case '2#120': /*IPTC caption*/ |
| 39 | + case '2#120': /*IPTC caption. mapped with exif ImageDescription*/ |
39 | 40 | $data['ImageDescription'] = self::convIPTC( $val, $c ); |
40 | 41 | break; |
41 | | - case '2#116': /* copyright */ |
| 42 | + case '2#116': /* copyright. Mapped with exif copyright */ |
42 | 43 | $data['Copyright'] = self::convIPTC( $val, $c ); |
43 | 44 | break; |
44 | | - case '2#080': /* byline */ |
| 45 | + case '2#080': /* byline. Mapped with exif Artist */ |
| 46 | + /* TODO: figure out how to handle byline title (2:85) */ |
45 | 47 | $data['Artist'] = self::convIPTC( $val, $c ); |
46 | 48 | break; |
47 | | - /* there are many many more that should be done */ |
| 49 | + case '2#025': /* keywords */ |
| 50 | + $data['Keywords'] = self::convIPTC( $val, $c ); |
| 51 | + break; |
| 52 | + case '2#101': /* Country (shown)*/ |
| 53 | + $data['CountryDest'] = self::convIPTC( $val, $c ); |
| 54 | + break; |
| 55 | + case '2#095': /* state/province (shown) */ |
| 56 | + $data['ProvinceOrStateDest'] = self::convIPTC( $val, $c ); |
| 57 | + break; |
| 58 | + case '2#090': /* city (Shown) */ |
| 59 | + $data['CityDest'] = self::convIPTC( $val, $c ); |
| 60 | + break; |
| 61 | + case '2#092': /* sublocation (shown) */ |
| 62 | + $data['SublocationDest'] = self::convIPTC( $val, $c ); |
| 63 | + break; |
| 64 | + case '2#005': /* object name/title */ |
| 65 | + $data['ObjectName'] = self::convIPTC( $val, $c ); |
| 66 | + break; |
| 67 | + case '2#040': /* special instructions */ |
| 68 | + $data['SpecialInstructions'] = self::convIPTC( $val, $c ); |
| 69 | + break; |
| 70 | + case '2#105': /* headline*/ |
| 71 | + $data['Headline'] = self::convIPTC( $val, $c ); |
| 72 | + break; |
| 73 | + case '2#110': /* credit */ |
| 74 | + /*"Identifies the provider of the objectdata, |
| 75 | + * not necessarily the owner/creator". */ |
| 76 | + $data['Credit'] = self::convIPTC( $val, $c ); |
| 77 | + break; |
| 78 | + case '2#115': /* source */ |
| 79 | + /* "Identifies the original owner of the intellectual content of the |
| 80 | + *objectdata. This could be an agency, a member of an agency or |
| 81 | + *an individual." */ |
| 82 | + $data['Source'] = self::convIPTC( $val, $c ); |
| 83 | + break; |
| 84 | + case '2#007': /* edit status (lead, correction, etc) */ |
| 85 | + $data['EditStatus'] = self::convIPTC( $val, $c ); |
| 86 | + break; |
| 87 | + case '2#010': /*urgency (1-8. 1 most, 5 normal, 8 low priority)*/ |
| 88 | + $data['Urgency'] = self::convIPTC( $val, $c ); |
| 89 | + break; |
| 90 | + case '2#022': |
| 91 | + /* "Identifies objectdata that recurs often and predictably... |
| 92 | + * Example: Euroweather" */ |
| 93 | + $data['FixtureIdentifier'] = self::convIPTC( $val, $c ); |
| 94 | + break; |
| 95 | + case '2#026': |
| 96 | + /* Content location code (iso 3166 + some custom things) |
| 97 | + * ex: TUR (for turkey), XUN (for UN), XSP (outer space) |
| 98 | + * See wikipedia article on iso 3166 and appendix D of iim std. */ |
| 99 | + $data['LocationDestCode'] = self::convIPTC( $val, $c ); |
| 100 | + break; |
| 101 | + case '2#027': |
| 102 | + /* Content location name. Full prinatable name |
| 103 | + * of location of photo. */ |
| 104 | + $data['LocationDest'] = self::convIPTC( $val, $c ); |
| 105 | + break; |
| 106 | + case '2#065': |
| 107 | + /* Originating Program. |
| 108 | + * Combine with Program version (2:70) if present. |
| 109 | + */ |
| 110 | + $software = self::convIPTC( $val, $c ); |
48 | 111 | |
| 112 | + if ( count( $software ) !== 1 ) { |
| 113 | + //according to iim standard this cannot have multiple values |
| 114 | + //so if there is more than one, something weird is happening, |
| 115 | + //and we skip it. |
| 116 | + wfDebugLog( 'iptc', 'IPTC: Wrong count on 2:65 Software field' ); |
| 117 | + break; |
| 118 | + } |
| 119 | + |
| 120 | + if ( isset( $parsed['2#070'] ) ) { |
| 121 | + //if a version is set for the software. |
| 122 | + $softwareVersion = self::convIPTC( $parsed['2#070'], $c ); |
| 123 | + unset($parsed['2#070']); |
| 124 | + $data['Software'] = array( array( $software[0], $softwareVersion[0] ) ); |
| 125 | + } else { |
| 126 | + $data['Software'] = $software; |
| 127 | + } |
| 128 | + |
| 129 | + |
| 130 | + break; |
| 131 | + case '2#075': |
| 132 | + /* Object cycle. |
| 133 | + * a for morning (am), p for evening, b for both */ |
| 134 | + $data['ObjectCycle'] = self::convIPTC( $val, $c ); |
| 135 | + break; |
| 136 | + case '2#100': |
| 137 | + /* Country/Primary location code. |
| 138 | + * "Indicates the code of the country/primary location where the |
| 139 | + * intellectual property of the objectdata was created" |
| 140 | + * unclear how this differs from 2#026 |
| 141 | + */ |
| 142 | + $data['CountryDestCode'] = self::convIPTC( $val, $c ); |
| 143 | + break; |
| 144 | + case '2#118': /*contact*/ |
| 145 | + $data['Contact'] = self::convIPTC( $val, $c ); |
| 146 | + break; |
| 147 | + case '2#122': |
| 148 | + /* Writer/Editor |
| 149 | + * "Identification of the name of the person involved in the writing, |
| 150 | + * editing or correcting the objectdata or caption/abstract." |
| 151 | + */ |
| 152 | + $data['Writer'] = self::convIPTC( $val, $c ); |
| 153 | + break; |
| 154 | + case '2#135': /* lang code */ |
| 155 | + $data['LanguageCode'] = self::convIPTC( $val, $c ); |
| 156 | + break; |
| 157 | + case '2#000': /* iim version */ |
| 158 | + // unlike other tags, this is a 2-byte binary number. |
| 159 | + //technically this is required if there is iptc data |
| 160 | + //but in practise it isn't always there. |
| 161 | + if ( strlen( $val[0] ) == 2 ) { |
| 162 | + //if is just to be paranoid. |
| 163 | + $versionValue = ord( substr( $val[0], 0, 1 ) ) * 256; |
| 164 | + $versionValue += ord( substr( $val[0], 1, 1 ) ); |
| 165 | + $data['iimVersion'] = $versionValue; |
| 166 | + } |
| 167 | + break; |
| 168 | + |
| 169 | + |
| 170 | + // TODO: the date related tags |
| 171 | + // does not do 2:103. Unsure if there is useful data there. |
| 172 | + // TODO: 2:15, 2:20 |
| 173 | + // other things not currently done, and not sure if should: |
| 174 | + // 2:12 |
| 175 | + // purposely does not do 2:125, 2:130, 2:131, |
| 176 | + // 2:47, 2:50, 2:45, 2:42, 2:8, 2:4, 2:3 |
| 177 | + // 2:200, 2:201, 2:202 |
| 178 | + // or the audio stuff (2:150 to 2:154) |
| 179 | + |
| 180 | + default: |
| 181 | + wfDebugLog( 'iptc', "Unsupported iptc tag: $tag. Value: " . implode( ',', $val )); |
| 182 | + break; |
49 | 183 | } |
50 | 184 | |
51 | 185 | } |
— | — | @@ -86,7 +220,7 @@ |
87 | 221 | $oldData = $data; |
88 | 222 | UtfNormal::quickIsNFCVerify( $data ); //make $data valid utf-8 |
89 | 223 | if ($data === $oldData) return $data; |
90 | | - else return convIPTCHelper ( $data, 'ISO-8859-1' ); //should this be windows-1252? |
| 224 | + else return self::convIPTCHelper ( $oldData, 'ISO-8859-1' ); //should this be windows-1252? |
91 | 225 | } |
92 | 226 | return $data; |
93 | 227 | } |
Index: branches/img_metadata/phase3/includes/media/Jpeg.php |
— | — | @@ -43,6 +43,18 @@ |
44 | 44 | return $metadata; |
45 | 45 | } |
46 | 46 | |
| 47 | + // Treat Software as a special case because in can contain |
| 48 | + // an array of (SoftwareName, Version). |
| 49 | + if (isset( $metadata['Software'] ) |
| 50 | + && is_array( $metadata['Software'] ) |
| 51 | + && is_array( $metadata['Software'][0]) |
| 52 | + && isset( $metadata['Software'][0][0] ) |
| 53 | + && isset( $metadata['Software'][0][1]) |
| 54 | + ) { |
| 55 | + $metadata['Software'] = $metadata['Software'][0][0] . ' (Version ' |
| 56 | + . $metadata['Software'][0][1] . ')'; |
| 57 | + } |
| 58 | + |
47 | 59 | foreach ( $metadata as &$val ) { |
48 | 60 | if ( is_array( $val ) ) { |
49 | 61 | $val = formatExif::flattenArray( $val ); |
Index: branches/img_metadata/phase3/languages/messages/MessagesEn.php |
— | — | @@ -3759,11 +3759,33 @@ |
3760 | 3760 | 'exif-gpsdifferential' => 'GPS differential correction', |
3761 | 3761 | 'exif-coordinate-format' => '$1° $2′ $3″ $4', |
3762 | 3762 | 'exif-jpegfilecomment' => 'JPEG file comment', |
| 3763 | +'exif-keywords' => 'Keywords', |
| 3764 | +'exif-countrydest' => 'Country shown', |
| 3765 | +'exif-countrydestcode' => 'Code for country shown', |
| 3766 | +'exif-provinceorstatedest' => 'Province or state shown', |
| 3767 | +'exif-citydest' => 'City shown', |
| 3768 | +'exif-sublocationdest' => 'Sublocation of city shown', |
| 3769 | +'exif-objectname' => 'Object name', |
| 3770 | +'exif-specialinstructions' => 'Special instructions', |
| 3771 | +'exif-headline' => 'Headline', |
| 3772 | +'exif-credit' => 'Credit/Provider', |
| 3773 | +'exif-source' => 'Source', |
| 3774 | +'exif-editstatus' => 'Editorial status of image', |
| 3775 | +'exif-urgency' => 'Urgency', |
| 3776 | +'exif-fixtureidentifier' => 'Fixture name', |
| 3777 | +'exif-locationdest' => 'Location depicted', |
| 3778 | +'exif-locationdestcode' => 'Code of location depicted', |
| 3779 | +'exif-objectcycle' => 'Time of day that media is intended for', |
| 3780 | +'exif-contact' => 'Contact information', |
| 3781 | +'exif-writer' => 'Writer', |
| 3782 | +'exif-languagecode' => 'Language', |
| 3783 | +'exif-iimversion' => 'IIM version', |
3763 | 3784 | |
3764 | 3785 | # Make & model, can be wikified in order to link to the camera and model name |
3765 | | -'exif-make-value' => '$1', # do not translate or duplicate this message to other languages |
3766 | | -'exif-model-value' => '$1', # do not translate or duplicate this message to other languages |
3767 | | -'exif-software-value' => '$1', # do not translate or duplicate this message to other languages |
| 3786 | +'exif-make-value' => '$1', # do not translate or duplicate this message to other languages |
| 3787 | +'exif-model-value' => '$1', # do not translate or duplicate this message to other languages |
| 3788 | +'exif-software-value' => '$1', # do not translate or duplicate this message to other languages |
| 3789 | +'exif-software-version-value' => '$1 (Version $2)', |
3768 | 3790 | |
3769 | 3791 | # EXIF attributes |
3770 | 3792 | 'exif-compression-1' => 'Uncompressed', |
— | — | @@ -3939,6 +3961,10 @@ |
3940 | 3962 | 'exif-gpsdirection-t' => 'True direction', |
3941 | 3963 | 'exif-gpsdirection-m' => 'Magnetic direction', |
3942 | 3964 | |
| 3965 | +'exif-objectcycle-a' => 'Morning only', |
| 3966 | +'exif-objectcycle-p' => 'Evening only', |
| 3967 | +'exif-objectcycle-b' => 'Both morning and evening', |
| 3968 | + |
3943 | 3969 | # External editor support |
3944 | 3970 | 'edit-externally' => 'Edit this file using an external application', |
3945 | 3971 | 'edit-externally-help' => '(See the [http://www.mediawiki.org/wiki/Manual:External_editors setup instructions] for more information)', |