* Added license information

* Fixed a bug in validate() that had to do with type casting, SHORT.','.LONG
  would previously never have been evaluated as its value "3,4" was typecast
  to 3 which matched SHORT.
* Added a new function, format(), to format the values of tags according to
  the Exif 2.2 specification.
This commit is contained in:
Ævar Arnfjörð Bjarmason 2005-05-08 16:04:44 +00:00
parent ff88d9df31
commit e293b51d0f

View file

@ -8,6 +8,21 @@ if (defined('MEDIAWIKI')) {
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @link http://exif.org/Exif2-2.PDF The Exif 2.2 specification
* @bug 1555, 1947
*/
@ -75,7 +90,7 @@ class Exif {
'BitsPerSample' => SHORT, # Number of bits per component
# "When a primary image is JPEG compressed, this designation is not"
# "necessary and is omitted." (p23)
'Compression' => SHORT, # Compression scheme
'Compression' => SHORT, # Compression scheme #p23
'PhotometricInterpretation' => SHORT, # Pixel composition #p23
'Orientation' => SHORT, # Orientation of image #p24
'SamplesPerPixel' => SHORT, # Number of components
@ -276,7 +291,7 @@ class Exif {
else
$this->mFlatExif[$key] = $val;
}
/**
* Produce a list of all Exif tags appropriate for user output
*
@ -363,31 +378,249 @@ class Exif {
* @return bool
*/
function validate( $tag, $val ) {
switch($this->mFlatExif[$tag]) {
case BYTE:
// Fucks up if not typecast
switch((string)$this->mFlatExif[$tag]) {
case (string)BYTE:
return $this->isByte( $val );
break;
case ASCII:
case (string)ASCII:
return $this->isASCII( $val );
break;
case SHORT:
case (string)SHORT:
return $this->isShort( $val );
break;
case LONG:
case (string)LONG:
return $this->isLong( $val );
case RATIONAL:
case (string)RATIONAL:
return $this->isRational( $val );
case UNDEFINED:
case (string)UNDEFINED:
return $this->isUndefined( $val );
case SLONG:
case (string)SLONG:
return $this->isSlong( $val );
case SRATIONAL:
case (string)SRATIONAL:
return $this->isSrational( $val );
case (string)SHORT.','.LONG:
return $this->isShort( $val ) || $this->isLong( $val );
default:
wfDebug( "Exif: The tag \"$tag\" had an invalid value: \"$val\"\n" );
return false;
break;
}
}
/**
* Numbers given by Exif user agents are often magical, that is they
* should be replaced by a detailed explanation depending on their
* value which most of the time are plain integers. This function
* formats Exif values into human readable form.
*
* @param string $tag The tag to be formatted
* @param mixed $val The value of the tag
* @return string
*/
function format( $tag, $val ) {
global $wgLang;
switch ($tag) {
case 'Compression':
switch ($val) {
case 1: case 6:
return $this->msg( $tag, $val );
}
case 'PhotometricInterpretation':
switch ($val) {
case 2: case 6:
return $this->msg( $tag, $val );
}
case 'Orientation':
switch ($val) {
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
return $this->msg( $tag, $val );
}
// TODO: If this field does not exist use 1
case 'PlanarConfiguration':
switch ($val) {
case 1: case 2:
return $this->msg( $tag, $val );
}
// TODO: YCbCrSubSampling
// TODO: YCbCrPositioning
// TODO: If this field does not exists use 2
case 'ResolutionUnit': #p26
switch ($val) {
case 2: case 3:
return $this->msg( $tag, $val );
}
// TODO: YCbCrCoefficients #p27 (see annex E)
case 'ExifVersion': case 'FlashpixVersion':
return "$val"/100;
case 'ColorSpace':
switch ($val) {
case 1: case 'FFFF.H':
return $this->msg( $tag, $val );
}
case 'ComponentsConfiguration':
switch ($val) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6:
return $this->msg( $tag, $val );
}
case 'DateTimeOriginal':
case 'DateTimeDigitized':
return $wgLang->timeanddate( wfTimestamp(TS_MW, $val) );
case 'ExposureProgram':
switch ($val) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
return $this->msg( $tag, $val );
}
case 'MeteringMode':
switch ($val) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 255:
return $this->msg( $tag, $val );
}
case 'LightSource':
switch ($val) {
case 0: case 1: case 2: case 3: case 4: case 9: case 10: case 11:
case 12: case 13: case 14: case 15: case 17: case 18: case 19: case 20:
case 21: case 22: case 23: case 24: case 255:
return $this->msg( $tag, $val );
}
// TODO: Flash
case 'SensingMethod':
switch ($val) {
case 1: case 2: case 3: case 4: case 5: case 7: case 8:
return $this->msg( $tag, $val );
}
case 'FileSource':
switch ($val) {
case 3:
return $this->msg( $tag, $val );
}
case 'SceneType':
switch ($val) {
case 1:
return $this->msg( $tag, $val );
}
case 'CustomRendered':
switch ($val) {
case 0: case 1:
return $this->msg( $tag, $val );
}
case 'ExposureMode':
switch ($val) {
case 0: case 1: case 2:
return $this->msg( $tag, $val );
}
case 'WhiteBalance':
switch ($val) {
case 0: case 1:
return $this->msg( $tag, $val );
}
case 'SceneCaptureType':
switch ($val) {
case 0: case 1: case 2: case 3:
return $this->msg( $tag, $val );
}
case 'GainControl':
switch ($val) {
case 0: case 1: case 2: case 3: case 4:
return $this->msg( $tag, $val );
}
case 'Contrast':
switch ($val) {
case 0: case 1: case 2:
return $this->msg( $tag, $val );
}
case 'Saturation':
switch ($val) {
case 0: case 1: case 2:
return $this->msg( $tag, $val );
}
case 'Sharpness':
switch ($val) {
case 0: case 1: case 2:
return $this->msg( $tag, $val );
}
case 'SubjectDistanceRange':
switch ($val) {
case 0: case 1: case 2: case 3:
return $this->msg( $tag, $val );
}
case 'GPSLatitudeRef':
switch ($val) {
case 'N': case 'S':
return $this->msg( $tag, $val );
}
case 'GPSLongitudeRef':
switch ($val) {
case 'E': case 'W':
return $this->msg( $tag, $val );
}
case 'GPSStatus':
switch ($val) {
case 'A': case 'V':
return $this->msg( $tag, $val );
}
case 'GPSMeasureMode':
switch ($val) {
case 2: case 3:
return $this->msg( $tag, $val );
}
case 'GPSSpeedRef':
switch ($val) {
case 'K': case 'M': case 'N':
return $this->msg( $tag, $val );
}
case 'GPSTrackRef':
switch ($val) {
case 'T': case 'M':
return $this->msg( $tag, $val );
}
case 'GPSImgDirectionRef':
switch ($val) {
case 'T': case 'M':
return $this->msg( $tag, $val );
}
case 'GPSDestLatitudeRef':
switch ($val) {
case 'N': case 'S':
return $this->msg( $tag, $val );
}
case 'GPSDestLongitudeRef':
switch ($val) {
case 'E': case 'W':
return $this->msg( $tag, $val );
}
case 'GPSDestBearingRef':
switch ($val) {
case 'T': case 'M':
return $this->msg( $tag, $val );
}
case 'GPSDateStamp':
return $wgLang->date( substr($val, 0, 4) . substr($val, 5, 2) . substr($val, 8, 2) . 000000 );
// This is not in the Exif standard, just a special
// case for our purposes which enables wikis to wikify
// the make and model to write articles about them.
case 'Make': case 'Model':
return wfMsg( strtolower( "exif-$tag-value" ), $val );
default:
return $val;
}
}
/**
* Conviniance function for format()
*
* @param string $tag The tag name to pass on
* @param string $val The value of the tag
* @return string A wfMsg of "exif-$tag-$val" in lower case
*/
function msg( $tag, $val ) {
return wfMsg( strtolower("exif-$tag-$val") );
}
}
} // MEDIAWIKI