using System;
using System.Collections;
using System.Text;
using com.drew.metadata;
using com.drew.lang;
using com.utils;
///
/// This class was first written by Drew Noakes in Java.
///
/// This is public domain software - that is, you can do whatever you want
/// with it, and include it software that is licensed under the GNU or the
/// BSD license, or whatever other licence you choose, including proprietary
/// closed source licenses. I do ask that you leave this header in tact.
///
/// If you make modifications to this code that you think would benefit the
/// wider community, please send me a copy and I'll post it on my site.
///
/// If you make use of this code, Drew Noakes will appreciate hearing
/// about it: drew@drewnoakes.com
///
/// Latest Java version of this software kept at
/// http://drewnoakes.com/
///
/// The C# class was made by Ferret Renaud:
/// renaud91@free.fr
/// If you find a bug in the C# code, feel free to mail me.
///
namespace com.drew.metadata.exif
{
///
/// Tag descriptor for almost every images
///
public class ExifDescriptor : TagDescriptor
{
///
/// Dictates whether rational values will be represented in decimal format in instances
/// where decimal notation is elegant (such as 1/2 -> 0.5, but not 1/3).
///
private readonly bool _allowDecimalRepresentationOfRationals = true;
///
/// Constructor of the object
///
/// a directory
public ExifDescriptor(Directory directory) : base(directory)
{
}
///
/// Returns a descriptive value of the the specified tag for this image.
/// Where possible, known values will be substituted here in place of the raw tokens actually
/// kept in the Exif segment.
/// If no substitution is available, the value provided by GetString(int) will be returned.
/// This and GetString(int) are the only 'get' methods that won't throw an exception.
///
/// the tag to find a description for
/// a description of the image's value for the specified tag, or null if the tag hasn't been defined.
public override string GetDescription(int tagType)
{
switch(tagType)
{
case ExifDirectory.TAG_ORIENTATION:
return GetOrientationDescription();
case ExifDirectory.TAG_RESOLUTION_UNIT:
return GetResolutionDescription();
case ExifDirectory.TAG_YCBCR_POSITIONING:
return GetYCbCrPositioningDescription();
case ExifDirectory.TAG_EXPOSURE_TIME:
return GetExposureTimeDescription();
case ExifDirectory.TAG_SHUTTER_SPEED:
return GetShutterSpeedDescription();
case ExifDirectory.TAG_FNUMBER:
return GetFNumberDescription();
case ExifDirectory.TAG_X_RESOLUTION:
return GetXResolutionDescription();
case ExifDirectory.TAG_Y_RESOLUTION:
return GetYResolutionDescription();
case ExifDirectory.TAG_THUMBNAIL_OFFSET:
return GetThumbnailOffSetDescription();
case ExifDirectory.TAG_THUMBNAIL_LENGTH:
return GetThumbnailLengthDescription();
case ExifDirectory.TAG_COMPRESSION_LEVEL:
return GetCompressionLevelDescription();
case ExifDirectory.TAG_SUBJECT_DISTANCE:
return GetSubjectDistanceDescription();
case ExifDirectory.TAG_METERING_MODE:
return GetMeteringModeDescription();
case ExifDirectory.TAG_WHITE_BALANCE:
return GetWhiteBalanceDescription();
case ExifDirectory.TAG_FLASH:
return GetFlashDescription();
case ExifDirectory.TAG_FOCAL_LENGTH:
return GetFocalLengthDescription();
case ExifDirectory.TAG_COLOR_SPACE:
return GetColorSpaceDescription();
case ExifDirectory.TAG_EXIF_IMAGE_WIDTH:
return GetExifImageWidthDescription();
case ExifDirectory.TAG_EXIF_IMAGE_HEIGHT:
return GetExifImageHeightDescription();
case ExifDirectory.TAG_FOCAL_PLANE_UNIT:
return GetFocalPlaneResolutionUnitDescription();
case ExifDirectory.TAG_FOCAL_PLANE_X_RES:
return GetFocalPlaneXResolutionDescription();
case ExifDirectory.TAG_FOCAL_PLANE_Y_RES:
return GetFocalPlaneYResolutionDescription();
case ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH:
return GetThumbnailImageWidthDescription();
case ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT:
return GetThumbnailImageHeightDescription();
case ExifDirectory.TAG_BITS_PER_SAMPLE:
return GetBitsPerSampleDescription();
case ExifDirectory.TAG_COMPRESSION:
return GetCompressionDescription();
case ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION:
return GetPhotometricInterpretationDescription();
case ExifDirectory.TAG_ROWS_PER_STRIP:
return GetRowsPerStripDescription();
case ExifDirectory.TAG_STRIP_BYTE_COUNTS:
return GetStripByteCountsDescription();
case ExifDirectory.TAG_SAMPLES_PER_PIXEL:
return GetSamplesPerPixelDescription();
case ExifDirectory.TAG_PLANAR_CONFIGURATION:
return GetPlanarConfigurationDescription();
case ExifDirectory.TAG_YCBCR_SUBSAMPLING:
return GetYCbCrSubsamplingDescription();
case ExifDirectory.TAG_EXPOSURE_PROGRAM:
return GetExposureProgramDescription();
case ExifDirectory.TAG_APERTURE:
return GetApertureValueDescription();
case ExifDirectory.TAG_MAX_APERTURE:
return GetMaxApertureValueDescription();
case ExifDirectory.TAG_SENSING_METHOD:
return GetSensingMethodDescription();
case ExifDirectory.TAG_EXPOSURE_BIAS:
return GetExposureBiasDescription();
case ExifDirectory.TAG_FILE_SOURCE:
return GetFileSourceDescription();
case ExifDirectory.TAG_SCENE_TYPE:
return GetSceneTypeDescription();
case ExifDirectory.TAG_COMPONENTS_CONFIGURATION:
return GetComponentConfigurationDescription();
case ExifDirectory.TAG_EXIF_VERSION:
return GetExifVersionDescription();
case ExifDirectory.TAG_FLASHPIX_VERSION:
return GetFlashPixVersionDescription();
case ExifDirectory.TAG_REFERENCE_BLACK_WHITE:
return GetReferenceBlackWhiteDescription();
case ExifDirectory.TAG_ISO_EQUIVALENT:
return GetIsoEquivalentDescription();
case ExifDirectory.TAG_THUMBNAIL_DATA:
return GetThumbnailDescription();
case ExifDirectory.TAG_XP_AUTHOR:
return GetXPAuthorDescription();
case ExifDirectory.TAG_XP_COMMENTS:
return GetXPCommentsDescription();
case ExifDirectory.TAG_XP_KEYWORDS:
return GetXPKeywordsDescription();
case ExifDirectory.TAG_XP_SUBJECT:
return GetXPSubjectDescription();
case ExifDirectory.TAG_XP_TITLE:
return GetXPTitleDescription();
default :
return _directory.GetString(tagType);
}
}
///
/// Returns the Thumbnail Description.
///
/// the Thumbnail Description.
private string GetThumbnailDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_DATA))
return null;
int[] thumbnailBytes =
_directory.GetIntArray(ExifDirectory.TAG_THUMBNAIL_DATA);
return BUNDLE["THUMBNAIL_BYTES", thumbnailBytes.Length.ToString()];
}
///
/// Returns the Iso Equivalent Description.
///
/// the Iso Equivalent Description.
private string GetIsoEquivalentDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_ISO_EQUIVALENT))
return null;
int isoEquiv = _directory.GetInt(ExifDirectory.TAG_ISO_EQUIVALENT);
if (isoEquiv < 50)
{
isoEquiv *= 200;
}
return isoEquiv.ToString();
}
///
/// Returns the Reference Black White Description.
///
/// the Reference Black White Description.
private string GetReferenceBlackWhiteDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_REFERENCE_BLACK_WHITE))
return null;
int[] ints =
_directory.GetIntArray(ExifDirectory.TAG_REFERENCE_BLACK_WHITE);
string[] sPos = new string[] {ints[0].ToString(), ints[1].ToString(),ints[2].ToString(),ints[3].ToString(),ints[4].ToString(),ints[5].ToString()};
return BUNDLE["POS",sPos];
}
///
/// Returns the Exif Version Description.
///
/// the Exif Version Description.
private string GetExifVersionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_EXIF_VERSION))
return null;
int[] ints = _directory.GetIntArray(ExifDirectory.TAG_EXIF_VERSION);
return ExifDescriptor.ConvertBytesToVersionString(ints);
}
///
/// Returns the Flash Pix Version Description.
///
/// the Flash Pix Version Description.
private string GetFlashPixVersionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FLASHPIX_VERSION))
return null;
int[] ints = _directory.GetIntArray(ExifDirectory.TAG_FLASHPIX_VERSION);
return ExifDescriptor.ConvertBytesToVersionString(ints);
}
///
/// Returns the Scene Type Description.
///
/// the Scene Type Description.
private string GetSceneTypeDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_SCENE_TYPE))
return null;
int sceneType = _directory.GetInt(ExifDirectory.TAG_SCENE_TYPE);
if (sceneType == 1)
{
return BUNDLE["DIRECTLY_PHOTOGRAPHED_IMAGE"];
}
else
{
return BUNDLE["UNKNOWN", sceneType.ToString()];
}
}
///
/// Returns the File Source Description.
///
/// the File Source Description.
private string GetFileSourceDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FILE_SOURCE))
return null;
int fileSource = _directory.GetInt(ExifDirectory.TAG_FILE_SOURCE);
if (fileSource == 3)
{
return BUNDLE["DIGITAL_STILL_CAMERA"];
}
else
{
return BUNDLE["UNKNOWN", fileSource.ToString()];
}
}
///
/// Returns the Exposure Bias Description.
///
/// the Exposure Bias Description.
private string GetExposureBiasDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_BIAS))
return null;
Rational exposureBias =
_directory.GetRational(ExifDirectory.TAG_EXPOSURE_BIAS);
return exposureBias.ToSimpleString(true);
}
///
/// Returns the Max Aperture Value Description.
///
/// the Max Aperture Value Description.
private string GetMaxApertureValueDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_MAX_APERTURE))
return null;
double apertureApex =
_directory.GetDouble(ExifDirectory.TAG_MAX_APERTURE);
double rootTwo = Math.Sqrt(2);
double fStop = Math.Pow(rootTwo, apertureApex);
return BUNDLE["APERTURE", fStop.ToString("0.#")];
}
///
/// Returns the Aperture Value Description.
///
/// the Aperture Value Description.
private string GetApertureValueDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_APERTURE))
return null;
double apertureApex = _directory.GetDouble(ExifDirectory.TAG_APERTURE);
double rootTwo = Math.Sqrt(2);
double fStop = Math.Pow(rootTwo, apertureApex);
return BUNDLE["APERTURE", fStop.ToString("0.#")];
}
///
/// Returns the Exposure Program Description.
///
/// the Exposure Program Description.
private string GetExposureProgramDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_PROGRAM))
return null;
// '1' means manual control, '2' program normal, '3' aperture priority,
// '4' shutter priority, '5' program creative (slow program),
// '6' program action(high-speed program), '7' portrait mode, '8' landscape mode.
switch (_directory.GetInt(ExifDirectory.TAG_EXPOSURE_PROGRAM))
{
case 1 :
return BUNDLE["MANUAL_CONTROL"];
case 2 :
return BUNDLE["PROGRAM_NORMAL"];
case 3 :
return BUNDLE["APERTURE_PRIORITY"];
case 4 :
return BUNDLE["SHUTTER_PRIORITY"];
case 5 :
return BUNDLE["PROGRAM_CREATIVE"];
case 6 :
return BUNDLE["PROGRAM_ACTION"];
case 7 :
return BUNDLE["PORTRAIT_MODE"];
case 8 :
return BUNDLE["LANDSCAPE_MODE"];
default :
return BUNDLE["UNKNOWN_PROGRAM", _directory.GetInt(ExifDirectory.TAG_EXPOSURE_PROGRAM).ToString()];
}
}
///
/// Returns the YCbCr Subsampling Description.
///
/// the YCbCr Subsampling Description.
private string GetYCbCrSubsamplingDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_YCBCR_SUBSAMPLING))
return null;
int[] positions =
_directory.GetIntArray(ExifDirectory.TAG_YCBCR_SUBSAMPLING);
if (positions[0] == 2 && positions[1] == 1)
{
return BUNDLE["YCBCR_422"];
}
else if (positions[0] == 2 && positions[1] == 2)
{
return BUNDLE["YCBCR_420"];
}
else
{
return BUNDLE["UNKNOWN"];
}
}
///
/// Returns the Planar Configuration Description.
///
/// the Planar Configuration Description.
private string GetPlanarConfigurationDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_PLANAR_CONFIGURATION))
return null;
// When image format is no compression YCbCr, this aValue shows byte aligns of YCbCr
// data. If aValue is '1', Y/Cb/Cr aValue is chunky format, contiguous for each subsampling
// pixel. If aValue is '2', Y/Cb/Cr aValue is separated and stored to Y plane/Cb plane/Cr
// plane format.
switch (_directory.GetInt(ExifDirectory.TAG_PLANAR_CONFIGURATION))
{
case 1 :
return BUNDLE["CHUNKY"];
case 2 :
return BUNDLE["SEPARATE"];
default :
return BUNDLE["UNKNOWN_CONFIGURATION"];
}
}
///
/// Returns the Samples Per Pixel Description.
///
/// the Samples Per Pixel Description.
private string GetSamplesPerPixelDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_SAMPLES_PER_PIXEL))
return null;
return BUNDLE["SAMPLES_PIXEL", _directory.GetString(ExifDirectory.TAG_SAMPLES_PER_PIXEL)];
}
///
/// Returns the Rows Per Strip Description.
///
/// the Rows Per Strip Description.
private string GetRowsPerStripDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_ROWS_PER_STRIP))
return null;
return BUNDLE["ROWS_STRIP", _directory.GetString(ExifDirectory.TAG_ROWS_PER_STRIP)];
}
///
/// Returns the Strip Byte Counts Description.
///
/// the Strip Byte Counts Description.
private string GetStripByteCountsDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_STRIP_BYTE_COUNTS))
return null;
return BUNDLE["BYTES", _directory.GetString(ExifDirectory.TAG_STRIP_BYTE_COUNTS)];
}
///
/// Returns the Photometric Interpretation Description.
///
/// the Photometric Interpretation Description.
private string GetPhotometricInterpretationDescription()
{
if (!_directory
.ContainsTag(ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION))
return null;
// Shows the color space of the image data components. '1' means monochrome,
// '2' means RGB, '6' means YCbCr.
switch (_directory
.GetInt(ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION))
{
case 1 :
return BUNDLE["MONOCHROME"];
case 2 :
return BUNDLE["RGB"];
case 6 :
return BUNDLE["YCBCR"];
default :
return BUNDLE["UNKNOWN_COLOUR_SPACE"];
}
}
///
/// Returns the Compression Description.
///
/// the Compression Description.
private string GetCompressionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_COMPRESSION))
return null;
// '1' means no compression, '6' means JPEG compression.
switch (_directory.GetInt(ExifDirectory.TAG_COMPRESSION))
{
case 1 :
return BUNDLE["NO_COMPRESSION"];
case 6 :
return BUNDLE["JPEG_COMPRESSION"];
default :
return BUNDLE["UNKNOWN_COMPRESSION"];
}
}
///
/// Returns the Bits Per Sample Description.
///
/// the Bits Per Sample Description.
private string GetBitsPerSampleDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_BITS_PER_SAMPLE))
return null;
return BUNDLE["BITS_COMPONENT_PIXEL",_directory.GetString(ExifDirectory.TAG_BITS_PER_SAMPLE)];
}
///
/// Returns the Thumbnail Image Width Description.
///
/// the Thumbnail Image Width Description.
private string GetThumbnailImageWidthDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH))
return null;
return BUNDLE["PIXELS", _directory.GetString(ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH)];
}
///
/// Returns the Thumbnail Image Height Description.
///
/// the Thumbnail Image Height Description.
private string GetThumbnailImageHeightDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT))
return null;
return BUNDLE["PIXELS", _directory.GetString(ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT)];
}
///
/// Returns the Focal Plane X Resolution Description.
///
/// the Focal Plane X Resolution Description.
private string GetFocalPlaneXResolutionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FOCAL_PLANE_X_RES))
return null;
Rational rational =
_directory.GetRational(ExifDirectory.TAG_FOCAL_PLANE_X_RES);
return BUNDLE["FOCAL_PLANE", rational.GetReciprocal().ToSimpleString(_allowDecimalRepresentationOfRationals),
GetFocalPlaneResolutionUnitDescription().ToLower()];
}
///
/// Returns the Focal Plane Y Resolution Description.
///
/// the Focal Plane Y Resolution Description.
private string GetFocalPlaneYResolutionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_COMPRESSION))
return null;
Rational rational =
_directory.GetRational(ExifDirectory.TAG_FOCAL_PLANE_Y_RES);
return BUNDLE["FOCAL_PLANE", rational.GetReciprocal().ToSimpleString(_allowDecimalRepresentationOfRationals),
GetFocalPlaneResolutionUnitDescription().ToLower()];
}
///
/// Returns the Focal Plane Resolution Unit Description.
///
/// the Focal Plane Resolution Unit Description.
private string GetFocalPlaneResolutionUnitDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FOCAL_PLANE_UNIT))
return null;
// Unit of FocalPlaneXResoluton/FocalPlaneYResolution. '1' means no-unit,
// '2' inch, '3' centimeter.
switch (_directory.GetInt(ExifDirectory.TAG_FOCAL_PLANE_UNIT))
{
case 1 :
return BUNDLE["NO_UNIT"];
case 2 :
return BUNDLE["INCHES"];
case 3 :
return BUNDLE["CM"];
default :
return "";
}
}
///
/// Returns the Exif Image Width Description.
///
/// the Exif Image Width Description.
private string GetExifImageWidthDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH))
return null;
return BUNDLE["PIXELS", _directory.GetInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH).ToString()];
}
///
/// Returns the Exif Image Height Description.
///
/// the Exif Image Height Description.
private string GetExifImageHeightDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT))
return null;
return BUNDLE["PIXELS", _directory.GetInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT).ToString()];
}
///
/// Returns the Color Space Description.
///
/// the Color Space Description.
private string GetColorSpaceDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_COLOR_SPACE))
return null;
int colorSpace = _directory.GetInt(ExifDirectory.TAG_COLOR_SPACE);
if (colorSpace == 1)
{
return BUNDLE["SRGB"];
}
else if (colorSpace == 65535)
{
return BUNDLE["UNDEFINED"];
}
else
{
return BUNDLE["UNKNOWN"];
}
}
///
/// Returns the Focal Length Description.
///
/// the Focal Length Description.
private string GetFocalLengthDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FOCAL_LENGTH))
return null;
Rational focalLength =
_directory.GetRational(ExifDirectory.TAG_FOCAL_LENGTH);
return BUNDLE["DISTANCE_MM", (focalLength.DoubleValue()).ToString("0.0##")];
}
///
/// Returns the Flash Description.
///
/// the Flash Description.
private string GetFlashDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FLASH))
return null;
// '0' means flash did not fire, '1' flash fired, '5' flash fired but strobe return
// light not detected, '7' flash fired and strobe return light detected.
switch (_directory.GetInt(ExifDirectory.TAG_FLASH))
{
case 0 :
return BUNDLE["NO_FLASH_FIRED"];
case 1 :
return BUNDLE["FLASH_FIRED"];
case 5 :
return BUNDLE["FLASH_FIRED_LIGHT_NOT_DETECTED"];
case 7 :
return BUNDLE["FLASH_FIRED_LIGHT_DETECTED"];
default :
return BUNDLE["UNKNOWN", _directory.GetInt(ExifDirectory.TAG_FLASH).ToString()];
}
}
///
/// Returns the White Balance Description.
///
/// the White Balance Description.
private string GetWhiteBalanceDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_WHITE_BALANCE))
return null;
// '0' means unknown, '1' daylight, '2' fluorescent, '3' tungsten, '10' flash,
// '17' standard light A, '18' standard light B, '19' standard light C, '20' D55,
// '21' D65, '22' D75, '255' other.
switch (_directory.GetInt(ExifDirectory.TAG_WHITE_BALANCE))
{
case 0 :
return BUNDLE["UNKNOWN"];
case 1 :
return BUNDLE["DAYLIGHT"];
case 2 :
return BUNDLE["FLOURESCENT"];
case 3 :
return BUNDLE["TUNGSTEN"];
case 10 :
return BUNDLE["FLASH"];
case 17 :
return BUNDLE["STANDARD_LIGHT"];
case 18 :
return BUNDLE["STANDARD_LIGHT_B"];
case 19 :
return BUNDLE["STANDARD_LIGHT_C"];
case 20 :
return BUNDLE["D55"];
case 21 :
return BUNDLE["D65"];
case 22 :
return BUNDLE["D75"];
case 255 :
return BUNDLE["OTHER"];
default :
return BUNDLE["UNKNOWN", _directory.GetInt(ExifDirectory.TAG_WHITE_BALANCE).ToString()];
}
}
///
/// Returns the Metering Mode Description.
///
/// the Metering Mode Description.
private string GetMeteringModeDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_METERING_MODE))
return null;
// '0' means unknown, '1' average, '2' center weighted average, '3' spot
// '4' multi-spot, '5' multi-segment, '6' partial, '255' other
int meteringMode = _directory.GetInt(ExifDirectory.TAG_METERING_MODE);
switch (meteringMode)
{
case 0 :
return BUNDLE["UNKNOWN"];
case 1 :
return BUNDLE["AVERAGE"];
case 2 :
return BUNDLE["CENTER_WEIGHTED_AVERAGE"];
case 3 :
return BUNDLE["SPOT"];
case 4 :
return BUNDLE["MULTI_SPOT"];
case 5 :
return BUNDLE["MULTI_SEGMENT"];
case 6 :
return BUNDLE["PARTIAL"];
case 255 :
return BUNDLE["OTHER"];
default :
return "";
}
}
///
/// Returns the Subject Distance Description.
///
/// the Subject Distance Description.
private string GetSubjectDistanceDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_SUBJECT_DISTANCE))
return null;
Rational distance =
_directory.GetRational(ExifDirectory.TAG_SUBJECT_DISTANCE);
return BUNDLE["METRES", (distance.DoubleValue()).ToString("0.0##")];
}
///
/// Returns the Compression Level Description.
///
/// the Compression Level Description.
private string GetCompressionLevelDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_COMPRESSION_LEVEL))
return null;
Rational compressionRatio =
_directory.GetRational(ExifDirectory.TAG_COMPRESSION_LEVEL);
string ratio =
compressionRatio.ToSimpleString(
_allowDecimalRepresentationOfRationals);
if (compressionRatio.IsInteger() && compressionRatio.IntValue() == 1)
{
return BUNDLE["BIT_PIXEL", ratio];
}
else
{
return BUNDLE["BITS_PIXEL", ratio];
}
}
///
/// Returns the Thumbnail Length Description.
///
/// the Thumbnail Length Description.
private string GetThumbnailLengthDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_LENGTH))
return null;
return BUNDLE["BYTES", _directory.GetString(ExifDirectory.TAG_THUMBNAIL_LENGTH)];
}
///
/// Returns the Thumbnail OffSet Description.
///
/// the Thumbnail OffSet Description.
private string GetThumbnailOffSetDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_OFFSET))
return null;
return BUNDLE["BYTES", _directory.GetString(ExifDirectory.TAG_THUMBNAIL_OFFSET)];
}
///
/// Returns the Y Resolution Description.
///
/// the Y Resolution Description.
private string GetYResolutionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_Y_RESOLUTION))
return null;
Rational resolution =
_directory.GetRational(ExifDirectory.TAG_Y_RESOLUTION);
return BUNDLE["DOTS_PER", resolution.ToSimpleString(_allowDecimalRepresentationOfRationals),GetResolutionDescription().ToLower()];
}
///
/// Returns the X Resolution Description.
///
/// the X Resolution Description.
private string GetXResolutionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_X_RESOLUTION))
return null;
Rational resolution =
_directory.GetRational(ExifDirectory.TAG_X_RESOLUTION);
return BUNDLE["DOTS_PER", resolution.ToSimpleString(_allowDecimalRepresentationOfRationals),GetResolutionDescription().ToLower()];
}
///
/// Returns the Exposure Time Description.
///
/// the Exposure Time Description.
private string GetExposureTimeDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_TIME))
return null;
return BUNDLE["SEC", _directory.GetString(ExifDirectory.TAG_EXPOSURE_TIME)];
}
///
/// Returns the Shutter Speed Description.
///
/// the Shutter Speed Description.
private string GetShutterSpeedDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_SHUTTER_SPEED))
return null;
// Incorrect math bug fixed by Hendrik Wördehoff - 20 Sep 2002
int apexValue = _directory.GetInt(ExifDirectory.TAG_SHUTTER_SPEED);
// int apexPower = (int)(Math.pow(2.0, apexValue) + 0.5);
// addition of 0.5 removed upon suggestion of Varuni Witana, who
// detected incorrect values for Canon cameras,
// which calculate both shutterspeed and exposuretime
int apexPower = (int) Math.Pow(2.0, apexValue);
return BUNDLE["SHUTTER_SPEED", apexPower.ToString()];
}
///
/// Returns the F Number Description.
///
/// the F Number Description.
private string GetFNumberDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_FNUMBER))
return null;
Rational fNumber = _directory.GetRational(ExifDirectory.TAG_FNUMBER);
return BUNDLE["APERTURE", fNumber.DoubleValue().ToString("0.#")];
}
///
/// Returns the YCbCr Positioning Description.
///
/// the YCbCr Positioning Description.
private string GetYCbCrPositioningDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_YCBCR_POSITIONING))
return null;
int yCbCrPosition =
_directory.GetInt(ExifDirectory.TAG_YCBCR_POSITIONING);
switch (yCbCrPosition)
{
case 1 :
return BUNDLE["CENTER_OF_PIXEL_ARRAY"];
case 2 :
return BUNDLE["DATUM_POINT"];
default :
return yCbCrPosition.ToString();
}
}
///
/// Returns the Orientation Description.
///
/// the Orientation Description.
private string GetOrientationDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_ORIENTATION))
return null;
int orientation = _directory.GetInt(ExifDirectory.TAG_ORIENTATION);
switch (orientation)
{
case 1 :
return BUNDLE["TOP_LEFT_SIDE"];
case 2 :
return BUNDLE["TOP_RIGHT_SIDE"];
case 3 :
return BUNDLE["BOTTOM_RIGHT_SIDE"];
case 4 :
return BUNDLE["BOTTOM_LEFT_SIDE"];
case 5 :
return BUNDLE["LEFT_SIDE_TOP"];
case 6 :
return BUNDLE["RIGHT_SIDE_TOP"];
case 7 :
return BUNDLE["RIGHT_SIDE_BOTTOM"];
case 8 :
return BUNDLE["LEFT_SIDE_BOTTOM"];
default :
return orientation.ToString();
}
}
///
/// Returns the Resolution Description.
///
/// the Resolution Description.
private string GetResolutionDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_RESOLUTION_UNIT))
return "";
// '1' means no-unit, '2' means inch, '3' means centimeter. Default aValue is '2'(inch)
int resolutionUnit =
_directory.GetInt(ExifDirectory.TAG_RESOLUTION_UNIT);
switch (resolutionUnit)
{
case 1 :
return BUNDLE["NO_UNIT"];
case 2 :
return BUNDLE["INCHES"];
case 3 :
return BUNDLE["CM"];
default :
return "";
}
}
///
/// Returns the Sensing Method Description.
///
/// the Sensing Method Description.
private string GetSensingMethodDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_SENSING_METHOD))
return null;
// '1' Not defined, '2' One-chip color area sensor, '3' Two-chip color area sensor
// '4' Three-chip color area sensor, '5' Color sequential area sensor
// '7' Trilinear sensor '8' Color sequential linear sensor, 'Other' reserved
int sensingMethod = _directory.GetInt(ExifDirectory.TAG_SENSING_METHOD);
switch (sensingMethod)
{
case 1 :
return BUNDLE["NOT_DEFINED"];
case 2 :
return BUNDLE["ONE_CHIP_COLOR"];
case 3 :
return BUNDLE["TWO_CHIP_COLOR"];
case 4 :
return BUNDLE["THREE_CHIP_COLOR"];
case 5 :
return BUNDLE["COLOR_SEQUENTIAL"];
case 7 :
return BUNDLE["TRILINEAR_SENSOR"];
case 8 :
return BUNDLE["COLOR_SEQUENTIAL_LINEAR"];
default :
return "";
}
}
///
/// Returns the XP author description.
///
/// the XP author description.
private string GetXPAuthorDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_XP_AUTHOR))
return null;
return Utils.Decode(_directory.GetByteArray(ExifDirectory.TAG_XP_AUTHOR), true);
}
///
/// Returns the XP comments description.
///
/// the XP comments description.
private string GetXPCommentsDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_XP_COMMENTS))
return null;
return Utils.Decode(_directory.GetByteArray(ExifDirectory.TAG_XP_COMMENTS), true);
}
///
/// Returns the XP keywords description.
///
/// the XP keywords description.
private string GetXPKeywordsDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_XP_KEYWORDS))
return null;
return Utils.Decode(_directory.GetByteArray(ExifDirectory.TAG_XP_KEYWORDS), true);
}
///
/// Returns the XP subject description.
///
/// the XP subject description.
private string GetXPSubjectDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_XP_SUBJECT))
return null;
return Utils.Decode(_directory.GetByteArray(ExifDirectory.TAG_XP_SUBJECT), true);
}
///
/// Returns the XP title description.
///
/// the XP title description.
private string GetXPTitleDescription()
{
if (!_directory.ContainsTag(ExifDirectory.TAG_XP_TITLE))
return null;
return Utils.Decode(_directory.GetByteArray(ExifDirectory.TAG_XP_TITLE), true);
}
///
/// Returns the Component Configuration Description.
///
/// the Component Configuration Description.
private string GetComponentConfigurationDescription()
{
int[] components =
_directory.GetIntArray(ExifDirectory.TAG_COMPONENTS_CONFIGURATION);
string[] componentStrings = { "", "Y", "Cb", "Cr", "R", "G", "B" };
StringBuilder componentConfig = new StringBuilder();
for (int i = 0; i < Math.Min(4, components.Length); i++)
{
int j = components[i];
if (j > 0 && j < componentStrings.Length)
{
componentConfig.Append(componentStrings[j]);
}
}
return componentConfig.ToString();
}
///
/// Takes a series of 4 bytes from the specified offSet, and converts these to a
/// well-known version number, where possible. For example, (hex) 30 32 31 30 == 2.10).
///
/// the four version values
/// the version as a string of form 2.10
public static string ConvertBytesToVersionString(int[] components)
{
StringBuilder version = new StringBuilder();
for (int i = 0; i < 4 && i < components.Length; i++)
{
if (i == 2)
version.Append('.');
string digit = ((char) components[i]).ToString();
if (i == 0 && "0".Equals(digit))
continue;
version.Append(digit);
}
return version.ToString();
}
}
}