[f-spot/taglib-metadata] Remove the home-grown TIFF parser, switch to Taglib#.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/taglib-metadata] Remove the home-grown TIFF parser, switch to Taglib#.
- Date: Tue, 6 Jul 2010 17:43:45 +0000 (UTC)
commit 6e33ba1bcad543d4eb3a531c9e3bdca90a257bc8
Author: Ruben Vermeersch <ruben savanne be>
Date: Tue Jul 6 19:32:48 2010 +0200
Remove the home-grown TIFF parser, switch to Taglib#.
lib/TagLib/TagLib | 2 +-
lib/TagLib/sources.mk | 4 +
src/Imaging/ImageFile.cs | 6 +-
src/Imaging/Tiff.cs | 1864 ++--------------------------------------------
src/MetadataStore.cs | 53 --
5 files changed, 62 insertions(+), 1867 deletions(-)
---
diff --git a/lib/TagLib/TagLib b/lib/TagLib/TagLib
index ea8e45d..21bfa3c 160000
--- a/lib/TagLib/TagLib
+++ b/lib/TagLib/TagLib
@@ -1 +1 @@
-Subproject commit ea8e45df929a5c18090ef7113806d04cb4f49b0d
+Subproject commit 21bfa3c553ba7c4194fdd0cfc3dabf6f1a594a09
diff --git a/lib/TagLib/sources.mk b/lib/TagLib/sources.mk
index 3dfca4e..754c948 100644
--- a/lib/TagLib/sources.mk
+++ b/lib/TagLib/sources.mk
@@ -108,6 +108,7 @@ SOURCES = \
TagLib/src/TagLib/IFD/Entries/ShortIFDEntry.cs \
TagLib/src/TagLib/IFD/Entries/SLongArrayIFDEntry.cs \
TagLib/src/TagLib/IFD/Entries/SLongIFDEntry.cs \
+ TagLib/src/TagLib/IFD/Entries/SRationalArrayIFDEntry.cs \
TagLib/src/TagLib/IFD/Entries/SRationalIFDEntry.cs \
TagLib/src/TagLib/IFD/Entries/SShortArrayIFDEntry.cs \
TagLib/src/TagLib/IFD/Entries/SShortIFDEntry.cs \
@@ -143,6 +144,7 @@ SOURCES = \
TagLib/src/TagLib/IFD/Tags/NikonVibrationReductionEntryTag.cs \
TagLib/src/TagLib/IFD/Tags/NikonWorldTimeEntryTag.cs \
TagLib/src/TagLib/IFD/Tags/PanasonicMakerNoteEntryTag.cs \
+ TagLib/src/TagLib/IFD/Tags/SonyMakerNoteEntryTag.cs \
TagLib/src/TagLib/Mpeg4/AppleTag.cs \
TagLib/src/TagLib/Mpeg4/Box.cs \
TagLib/src/TagLib/Mpeg4/BoxFactory.cs \
@@ -182,7 +184,9 @@ SOURCES = \
TagLib/src/TagLib/Tiff/BaseTiffFile.cs \
TagLib/src/TagLib/Tiff/Codec.cs \
TagLib/src/TagLib/Tiff/File.cs \
+ TagLib/src/TagLib/Tiff/Arw/File.cs \
TagLib/src/TagLib/Tiff/Cr2/File.cs \
+ TagLib/src/TagLib/Tiff/Dng/File.cs \
TagLib/src/TagLib/Tiff/Nef/File.cs \
TagLib/src/TagLib/WavPack/File.cs \
TagLib/src/TagLib/WavPack/StreamHeader.cs \
diff --git a/src/Imaging/ImageFile.cs b/src/Imaging/ImageFile.cs
index 8dc8a32..f4b08eb 100644
--- a/src/Imaging/ImageFile.cs
+++ b/src/Imaging/ImageFile.cs
@@ -45,7 +45,7 @@ namespace FSpot.Imaging {
name_table [".arw"] = typeof (FSpot.Imaging.Tiff.NefFile);
name_table [".rw2"] = typeof (FSpot.Imaging.DCRawFile);
name_table [".tiff"] = typeof (BaseImageFile);
- name_table [".tif"] = typeof (FSpot.Imaging.Tiff.TiffFile);
+ name_table [".tif"] = typeof (BaseImageFile);
name_table [".orf"] = typeof (FSpot.Imaging.Tiff.NefFile);
name_table [".srf"] = typeof (FSpot.Imaging.Tiff.NefFile);
name_table [".dng"] = typeof (FSpot.Imaging.Tiff.DngFile);
@@ -178,9 +178,13 @@ namespace FSpot.Imaging {
using (var metadata_file = Metadata.Parse (uri)) {
Orientation = metadata_file.ImageTag.Orientation;
+ ExtractMetadata (metadata_file);
}
}
+ protected virtual void ExtractMetadata (TagLib.Image.File metadata) {
+ }
+
~BaseImageFile ()
{
Dispose ();
diff --git a/src/Imaging/Tiff.cs b/src/Imaging/Tiff.cs
index 8debe90..635bab3 100644
--- a/src/Imaging/Tiff.cs
+++ b/src/Imaging/Tiff.cs
@@ -1,1229 +1,17 @@
using FSpot;
using FSpot.Utils;
-using SemWeb;
using System;
using System.IO;
using System.Collections.Generic;
using Hyena;
+using TagLib;
using TagLib.Image;
+using TagLib.IFD;
+using TagLib.IFD.Entries;
+using TagLib.IFD.Tags;
namespace FSpot.Imaging.Tiff {
-
- // This is primarily to preserve the names from the specification
- // because they differ from the tiff standard names
- public enum NiffId : ushort {
- SubfileType = 0x00fe,
- PelPathLength = 0x0100,
- LineProgressionLength = 257,
- BitsPerSample = 0x0101,
- PhotometricInterpretation = 0x0106,
- DataOffset = 0x0111,
- SamplesPerPixel = 0x0115,
- DataByteCounts = 0x0117,
- PelPathResolution = 0x011a,
- LineProgressionResolution = 0x011b,
- ResolutionUnit = 0x0128,
- ColumnsPerPelPath = 322,
- RowsPerLineProgression = 323,
- Rotation = 33465,
- NavyCompression = 33466,
- TileIndex = 33467
- }
-
- public enum TagGPS : ushort {
- GPSVersionID = 0x0000,
- GPSLatitudeRef = 0x0001,
- GPSLatitude = 0x0002,
- GPSLongitudeRef = 0x0003,
- GPSLongitue = 0x0004,
- GPSAltitudeRef = 0x0005,
- GPSAltitude = 0x0006,
- GPSTimeStamp = 0x0007,
- GPSSatellites = 0x0008,
- GPSStatus = 0x0009,
- GPSMeasureMode = 0x000a,
- GPSDOP = 0x000b,
- GPSSpeedRef = 0x000c,
- GPSSpeed = 0x000d,
- GPSTrackRef = 0x000e,
- GPSTrack = 0x000f,
- GPSImgDirectionRef = 0x0010,
- GPSImgDirection = 0x0011,
- GPSMapDatum = 0x0012,
- GPSDestLatitudeRef = 0x0013,
- GPSDestLatitude = 0x0014,
- GPSDestLongitudeRef = 0x0015,
- GPSDestLongitude = 0x0016,
- GPSDestBearingRef = 0x0017,
- GPSDestBearing = 0x0018,
- GPSDestDistanceRef = 0x0019,
- GPSDestDistance = 0x001a,
- GPSProcessingMethod = 0x001b,
- GPSAreaInformation = 0x001c,
- GPSDateStamp = 0x001d,
- GPSDifferential = 0x001e
- }
-
- public enum TagId : ushort {
- InteroperabilityIndex = 0x0001,
- InteroperabilityVersion = 0x0002,
-
- NewSubfileType = 0x00fe,
- SubfileType = 0x00ff,
-
- ImageWidth = 0x0100,
- ImageLength = 0x0101,
- BitsPerSample = 0x0102,
- Compression = 0x0103,
- PhotometricInterpretation = 0x0106,
- FillOrder = 0x010a,
- DocumentName = 0x010d,
- ImageDescription = 0x010e,
- Make = 0x010f,
- Model = 0x0110,
- StripOffsets = 0x0111,
- SamplesPerPixel = 0x0115,
- RowsPerStrip = 0x0116,
- StripByteCounts = 0x0117,
- XResolution = 0x011a,
- YResolution = 0x011b,
- PlanarConfiguration = 0x011c,
-
- T4Options = 0x0124,
- T6Options = 0x0125,
-
- ResolutionUnit = 0x0128,
- TransferFunction = 0x012d,
- Software = 0x0131,
- DateTime = 0x0132,
- Artist = 0x013b,
- WhitePoint = 0x013e,
- PrimaryChromaticities = 0x013f,
-
- HalftoneHints = 0x0141,
- // Tiled images
- TileWidth = 0x0142,
- TileLength = 0x0143,
- TileOffsets = 0x0144,
- TileByteCounts = 0x0145,
-
- SubIFDs = 0x014a, // TIFF-EP
-
- // CMYK images
- InkSet = 0x014c,
- NumberOfInks = 0x014e,
- InkNames = 0x014d,
- DotRange = 0x0150,
- TargetPrinter = 0x0151,
- ExtraSamples = 0x0152,
- SampleFormat = 0x0153,
- SMinSampleValue = 0x0154,
- SMaxSampleValue = 0x0155,
-
- TransferRange = 0x0156,
-
- ClipPath = 0x0157, // TIFF PageMaker Technote #2.
-
- JPEGTables = 0x015b, // TIFF-EP
-
- JPEGProc = 0x0200,
- JPEGInterchangeFormat = 0x0201,
- JPEGInterchangeFormatLength = 0x0202,
- JPEGRestartInterval = 0x0203,
- JPEGLosslessPredictors = 0x0205,
- JPEGPointTransforms = 0x0206,
- JPEGQTables = 0x0207,
- JPEGDCTables = 0x0208,
- JPEGACTables = 0x0209,
-
- YCbCrCoefficients = 0x0211,
- YCbCrSubSampling = 0x0212,
- YCbCrPositioning = 0x0213,
-
- ReferenceBlackWhite = 0x0214,
- RelatedImageFileFormat = 0x1000,
- RelatedImageWidth = 0x1001,
- RelatedImageLength = 0x1002,
- CFARepeatPatternDim = 0x828d,
- CFAPattern = 0x828e,
- BatteryLevel = 0x828f,
- Copyright = 0x8298,
- ExposureTime = 0x829a,
- FNumber = 0x829d,
-
- // These are from the NIFF spec and only really valid when the header begins with IIN1
- // see the NiffTag enum for the specifcation specific names
- Rotation = 0x82b9,
- NavyCompression = 0x82ba,
- TileIndex = 0x82bb,
- // end NIFF specific
-
- IPTCNAA = 0x83bb,
-
- PhotoshopPrivate = 0x8649,
-
- ExifIfdPointer = 0x8769,
- InterColorProfile = 0x8773,
- ExposureProgram = 0x8822,
- SpectralSensitivity = 0x8824,
- GPSInfoIfdPointer = 0x8825,
- ISOSpeedRatings = 0x8827,
- OECF = 0x8828,
- ExifVersion = 0x9000,
- DateTimeOriginal = 0x9003,
- DateTimeDigitized = 0x9004,
- ComponentsConfiguration = 0x9101,
- CompressedBitsPerPixel = 0x9102,
- ShutterSpeedValue = 0x9201,
- ApertureValue = 0x9202,
- BrightnessValue = 0x9203,
- ExposureBiasValue = 0x9204,
- MaxApertureValue = 0x9205,
- SubjectDistance = 0x9206,
- MeteringMode = 0x9207,
- LightSource = 0x9208,
- Flash = 0x9209,
- FocalLength = 0x920a,
-
- FlashEnergy_TIFFEP = 0x920b,// TIFF-EP
- SpacialFrequencyResponse = 0x920c,// TIFF-EP
- Noise = 0x920d,// TIFF-EP
- FocalPlaneXResolution_TIFFEP = 0x920e,// TIFF-EP
- FocalPlaneYResolution_TIFFEP = 0x920f,// TIFF-EP
- FocalPlaneResolutionUnit_TIFFEP = 0x9210,// TIFF-EP
- ImageName = 0x9211,// TIFF-EP
- SecurityClassification = 0x9212,// TIFF-EP
-
- ImageHistory = 0x9213, // TIFF-EP null separated list
-
- SubjectArea = 0x9214,
-
- ExposureIndex_TIFFEP = 0x9215, // TIFF-EP
- TIFFEPStandardID = 0x9216, // TIFF-EP
- SensingMethod_TIFFEP = 0x9217, // TIFF-EP
-
- MakerNote = 0x927c,
- UserComment = 0x9286,
- SubSecTime = 0x9290,
- SubSecTimeOriginal = 0x9291,
- SubSecTimeDigitized = 0x9292,
- FlashPixVersion = 0xa000,
- ColorSpace = 0xa001,
- PixelXDimension = 0xa002,
- PixelYDimension = 0xa003,
- RelatedSoundFile = 0xa004,
- InteroperabilityIfdPointer = 0xa005,
- FlashEnergy = 0xa20b,
- SpatialFrequencyResponse = 0xa20c,
- FocalPlaneXResolution = 0xa20e,
- FocalPlaneYResolution = 0xa20f,
- FocalPlaneResolutionUnit = 0xa210,
- SubjectLocation = 0xa214,
- ExposureIndex = 0xa215,
- SensingMethod = 0xa217,
- FileSource = 0xa300,
- SceneType = 0xa301,
- ExifCFAPattern = 0xa302,
- CustomRendered = 0xa401,
- ExposureMode = 0xa402,
- WhiteBalance = 0xa403,
- DigitalZoomRatio = 0xa404,
- FocalLengthIn35mmFilm = 0xa405,
- SceneCaptureType = 0xa406,
- GainControl = 0xa407,
- Contrast = 0xa408,
- Saturation = 0xa409,
- Sharpness = 0xa40a,
- DeviceSettingDescription = 0xa40b,
- SubjectDistanceRange = 0xa40c,
- ImageUniqueId = 0xa420,
-
- // The Following IDs are not described the EXIF spec
- Gamma = 0xa500,
-
- // The XMP spec declares that XMP data should live 0x2bc when
- // embedded in tiff images.
- XMP = 0x02bc,
-
- // from the dng spec
- DNGVersion = 0xc612, // Ifd0
- DNGBackwardVersion = 0xc613, // Ifd0
- UniqueCameraModel = 0xc614, // Ifd0
- LocalizedCameraModel = 0xc615, // Ifd0
- CFAPlaneColor = 0xc616, // RawIfd
- CFALayout = 0xc617, // RawIfd
- LinearizationTable = 0xc618, // RawIfd
- BlackLevelRepeatDim = 0xc619, // RawIfd
- BlackLevel = 0xc61a, // RawIfd
- BlackLevelDeltaH = 0xc61b, // RawIfd
- BlackLevelDeltaV = 0xc61c, // RawIfd
- WhiteLevel = 0xc61d, // RawIfd
- DefaultScale = 0xc61e, // RawIfd
- DefaultCropOrigin = 0xc61f, // RawIfd
- DefaultCropSize = 0xc620, // RawIfd
- ColorMatrix1 = 0xc621, // Ifd0
- ColorMatrix2 = 0xc622, // Ifd0
- CameraCalibration1 = 0xc623, // Ifd0
- CameraCalibration2 = 0xc624, // Ifd0
- ReductionMatrix1 = 0xc625, // Ifd0
- ReductionMatrix2 = 0xc626, // Ifd0
- AnalogBalance = 0xc627, // Ifd0
- AsShotNetural = 0xc628, // Ifd0
- AsShotWhiteXY = 0xc629, // Ifd0
- BaselineExposure = 0xc62a, // Ifd0
- BaselineNoise = 0xc62b, // Ifd0
- BaselineSharpness = 0xc62c, // Ifd0
- BayerGreeSpit = 0xc62d, // Ifd0
- LinearResponseLimit = 0xc62e, // Ifd0
- CameraSerialNumber = 0xc62f, // Ifd0
- LensInfo = 0xc630, // Ifd0
- ChromaBlurRadius = 0xc631, // RawIfd
- AntiAliasStrength = 0xc632, // RawIfd
- DNGPrivateData = 0xc634, // Ifd0
-
- MakerNoteSafety = 0xc635, // Ifd0
-
- // The Spec says BestQualityScale is 0xc635 but it appears to be wrong
- //BestQualityScale = 0xc635, // RawIfd
- BestQualityScale = 0xc63c, // RawIfd this looks like the correct value
-
- CalibrationIlluminant1 = 0xc65a, // Ifd0
- CalibrationIlluminant2 = 0xc65b, // Ifd0
-
- // Print Image Matching data
- PimIfdPointer = 0xc4a5
- }
-
- public struct SRational {
- public int Numerator;
- public int Denominator;
-
- public SRational (byte [] raw_data, int offset, bool little)
- {
- Numerator = BitConverter.ToInt32 (raw_data, offset, little);
- Denominator = BitConverter.ToInt32 (raw_data, offset, little);
- }
-
- public SRational (int numerator, int denominator)
- {
- Numerator = numerator;
- Denominator = denominator;
- }
-
- public static SRational BitwiseCopy (Rational rational)
- {
- SRational result;
-
- result.Numerator = unchecked ((int) rational.Numerator);
- result.Denominator = unchecked ((int) rational.Denominator);
- return result;
- }
-
- public override string ToString ()
- {
- if (Numerator == 0 || Denominator == 0)
- return String.Format ("{0}/{1}", Numerator, Denominator);
- else if (Numerator % Denominator == 0)
- return String.Format ("{0}", Numerator / Denominator);
- else if (Denominator % Numerator == 0)
- return String.Format ("1/{0}", Denominator / Numerator);
-
- return String.Format ("{0}/{1}", Numerator, Denominator);
- }
-
- public double Value {
- get {
- return Numerator / (double)Denominator;
- }
- }
- }
-
- public struct Rational {
- public uint Numerator;
- public uint Denominator;
-
- public Rational (uint numerator, uint denominator)
- {
- Numerator = numerator;
- Denominator = denominator;
- }
-
- public Rational (string value)
- {
- string [] vals = value.Split ('/');
- if (vals.Length == 2) {
- this.Numerator = UInt32.Parse (vals [0]);
- this.Denominator = UInt32.Parse (vals [1]);
- return;
- } if (vals.Length == 1) {
- double tmp = Double.Parse (value);
- this.Numerator = (uint) (tmp * 100000);
- this.Denominator = 100000;
- } else
- throw new ParseException ("unable to parse rational value");
- }
-
- public override string ToString ()
- {
- if (Numerator == 0 || Denominator == 0)
- return String.Format ("{0}/{1}", Numerator, Denominator);
- else if (Numerator % Denominator == 0)
- return String.Format ("{0}", Numerator / Denominator);
- else if (Denominator % Numerator == 0)
- return String.Format ("1/{0}", Denominator / Numerator);
-
- return String.Format ("{0}/{1}", Numerator, Denominator);
- }
-
- public double Value {
- get {
- return Numerator / (double)Denominator;
- }
- }
- }
-
- struct UserComment {
- string Charset;
- public string Value;
-
- public UserComment (string value)
- {
- Charset = null;
- Value = value;
- }
-
- public UserComment (byte [] raw_data, bool little)
- {
- if (raw_data.Length == 8 || raw_data.Length == 0) {
- Charset = null;
- Value = String.Empty;
- return;
- } else if (raw_data.Length < 8) {
- throw new Exception ("Invalid UserComment value, no charset found");
- }
-
- string charset = System.Text.Encoding.ASCII.GetString (raw_data, 0, 8);
- System.Text.Encoding enc;
-
- switch (charset) {
- case "ASCII\0\0\0":
- enc = System.Text.Encoding.ASCII;
- break;
- case "UNICODE\0":
- case "Unicode\0":
- enc = new System.Text.UnicodeEncoding (! little, true);
- break;
- case "JIS\0\0\0\0\0":
- // FIXME this requires mono locale extras
- try {
- enc = System.Text.Encoding.GetEncoding ("euc-jp");
- } catch {
- Log.Warning ("missing jis0208 encoding");
- enc = System.Text.Encoding.Default;
- }
- break;
- case "\0\0\0\0\0\0\0\0":
- // FIXME the spec says to use the local encoding in this case, we could probably
- // do something smarter, but whatever.
- enc = System.Text.Encoding.Default;
- break;
- default:
- enc = null;
- throw new ParseException (System.String.Format ("Invalid charset name: {0}", charset));
- }
-
- Charset = charset;
- // for (int i = 0; i < raw_data.Length; i++)
- // System.Console.WriteLine ("{0} - \"{1}\"", raw_data [i].ToString ("x"), raw_data [i]);
- Value = enc.GetString (raw_data, 8, raw_data.Length - 8).Trim('\0');
- }
-
- public byte [] GetBytes (bool is_little)
- {
- bool ascii = true;
- string description = Value;
- System.Text.Encoding enc;
- string heading;
-
- for (int i = 0; i < description.Length; i++) {
- if (description [i] > 127) {
- ascii = false;
- break;
- }
- }
-
- if (ascii) {
- heading = "ASCII\0\0\0";
- enc = new System.Text.ASCIIEncoding ();
- } else {
- heading = "UNICODE\0";
- enc = new System.Text.UnicodeEncoding (! is_little, true);
- }
-
- int len = enc.GetByteCount (description);
- byte [] data = new byte [len + heading.Length];
- System.Text.Encoding.ASCII.GetBytes (heading, 0, heading.Length, data, 0);
- enc.GetBytes (Value, 0, Value.Length, data, heading.Length);
-
- UserComment c = new UserComment (data, is_little);
- Log.DebugFormat ("old = \"{0}\" new = \"{1}\" heading = \"{2}\"", c.Value, description, heading);
- return data;
- }
-
- public override string ToString ()
- {
- return String.Format ("({0},charset={1})", Value, Charset);
- }
- }
-
- public struct CFAPattern {
- public ushort Rows;
- public ushort Columns;
- public byte [] Values;
-
- public CFAPattern (byte [] raw_data, bool little)
- {
- Columns = BitConverter.ToUInt16 (raw_data, 0, little);
- Rows = BitConverter.ToUInt16 (raw_data, 2, little);
-
- Values = new byte [Rows * Columns];
- // FIXME the contents here may differ from what we
- // expect, but for now we won't throw an exception
- // since the entry still may be a valid structure.
- if (raw_data.Length -4 < Values.Length)
- System.Array.Copy (raw_data, 4, Values, 0, Values.Length);
- }
-
- /*
- * Note the Exif spec defines a CFA pattern tag that includes the row and column counts as shorts
- * inside the first four bytes of the entry. The Tiff-EP standard define the CFARepeatPattern tag
- * that contains the row and column counts presumably since the Exif version wouldn't allow you to
- * alter the endian of the file without knowing the tag layout.
- */
-
- public CFAPattern (ushort rows, ushort cols, byte [] raw_data, bool little)
- {
- Columns = rows;
- Rows = cols;
- Values = new byte [rows * cols];
- System.Array.Copy (raw_data, 0, Values, 0, Values.Length);
- }
- }
-
- public struct OECFTable {
- public ushort Rows;
- public ushort Columns;
- public string [] Names;
- public SRational [] Values;
-
- public OECFTable (byte [] raw_data, bool little)
- {
- Columns = BitConverter.ToUInt16 (raw_data, 0, little);
- Rows = BitConverter.ToUInt16 (raw_data, 2, little);
- Names = new string [Columns];
- Values = new SRational [Columns * Rows];
-
- int pos = 2;
- int i;
- int type_size = DirectoryEntry.GetTypeSize (EntryType.SRational);
-
- for (i = 0; i < Names.Length; i++)
- Names [i] = ReadString (raw_data, ref pos);
-
- for (i = 0; i < Values.Length; i++)
- Values [i] = new SRational (raw_data, pos + i * type_size, little);
-
- }
-
- public string ReadString (byte [] data, ref int pos)
- {
- int start = pos;
- for (; pos < data.Length; pos++) {
- if (data [pos] == 0)
- break;
- }
- return System.Text.Encoding.ASCII.GetString (data, start, pos - start);
- }
- }
-
- public enum ExtraSamples {
- Unspecified = 0,
- AssociatedAlpha = 1,
- UnassociatedAlpa = 2
- }
-
- public enum FileSource {
- DCF = 3,
- }
-
- public enum PhotometricInterpretation : ushort {
- WhiteIsZero = 0,
- BlackIsZero = 1,
- RGB = 2,
- PaletteColor = 3,
- TransparencyMask = 4,
- Separated = 5, // CMYK
- YCbCr = 6,
- CIELab = 8,
- ICCLab = 9,
- ITULab = 10,
- LogL = 32844, // Log Luminance
- LogLUV = 32845,
- ColorFilterArray = 32803, // ColorFilterArray... the good stuff
- LinearRaw = 34892 // DBG LinearRaw
- }
-
- public enum PlanarConfiguration {
- Chunky = 1,
- Planar = 2
- }
-
- public enum Compression {
- Packed = 1,
- Huffman = 2,
- T4 = 3,
- T6 = 4,
- LZW = 5,
- JPEG = 6,
- JPEGStream = 7, // TIFF-EP stores full jpeg stream
- Deflate = 8,
- JBIG = 9,
- JBIG_MRC,
- PackBits = 32773,
- NikonCompression = 34713,
- Deflate_experimental = 0x80b2
- }
-
- public enum JPEGProc {
- BaselineSequencial = 1,
- LosslessHuffman = 14,
- }
-
- public enum SubfileType {
- FullResolution = 1,
- ReducedResolution = 2,
- PageOfMultipage = 3
- }
-
- public enum ExposureProgram {
- NotDefined = 0,
- Manual = 1,
- NormalProgram = 2, // Normal Program
- AperturePriority = 3, // Aperture priority
- ShutterPriorty = 4, // Shutter priority
- CreativeProgram = 5, // Creative program
- ActionProgram = 6, // Action program
- PortraitMode = 7, // Portrait mode
- LandscapeMode = 8 // Landscape mode
- }
-
- public enum ExposureMode {
- Auto = 0,
- Manual = 1,
- AutoBracket = 2
- }
-
- public enum CustomRendered : ushort {
- Normal = 0,
- Custom = 1
- }
-
- public enum SceneType {
- DirectlyPhotographed = 1
- }
-
- public enum MeteringMode {
- Uknown = 0,
- Average = 1,
- CenterWeightedAverage = 2,
- Spot = 3,
- MulitSpot = 4,
- Pattern = 5,
- Partial = 6,
- }
-
- public enum SceneCaptureType : ushort {
- Standard = 0,
- Landscape = 1,
- Portrait = 2,
- NightScene = 3
- }
-
- public enum GainControl : ushort {
- None = 0,
- LowGainUp = 1,
- HighGainUp = 2,
- LowGainDown = 3,
- HighGainDown = 4
- }
-
- public enum Contrast : ushort {
- Normal = 0,
- Soft = 1,
- Hard = 2
- }
-
- public enum Saturation : ushort {
- Normal = 0,
- Low = 1,
- High = 2
- }
-
- public enum WhiteBalance : ushort {
- Auto = 0,
- Manual = 1
- }
-
- public enum Sharpness : ushort {
- Normal = 0,
- Soft = 1,
- Hard = 2
- }
-
- public enum LightSource {
- Unknown = 0,
- Daylight = 1,
- Fluorescent = 2,
- Tungsten = 3,
- Fash = 4,
- FineWeather = 9,
- CloudyWeather = 10,
- Shade = 11,
- DaylightFluorescent = 12,
- DaylightWhiteFluorescent = 13,
- CoolWhiteFluorescent = 14,
- WhiteFluorescent = 15,
- StandardLightA = 17,
- StandardLightB = 18,
- StandardLightC = 19,
- D55 = 20,
- D65 = 21,
- D75 = 22,
- D50 = 23,
- ISOStudioTungsten = 24,
- OtherSource = 255
- }
-
- public enum ColorSpace {
- StandardRGB = 1, // sRGB
- AdobeRGB = 2,
- Uncalibrated = 0xffff
- }
-
- public enum ComponentsConfiguration {
- DoesNotExist = 0,
- Y = 1,
- Cb = 2,
- Cr = 3,
- R = 4,
- G = 6,
- }
-
- public enum ResolutionUnit : ushort {
- Uncalibrated = 1,
- Inch = 2,
- Centimeter = 3
- }
-
- public enum SensingMethod : short {
- NotDefined = 1,
- OneChipColorAreaSensor = 2,
- TwoChipColorAreaSensor = 3,
- ThreeChipColorAreaSensor = 4,
- ColorSequentialAreaSensor = 5,
- TrilinearSensor = 7,
- ColorSequentialLinearSensor = 8
- }
-
- [System.Flags]
- public enum NewSubfileType : uint {
- ReducedResolution = 1,
- PageOfMultipage= 1 << 1,
- TransparencyMask = 1 << 2
- }
-
- public enum EntryType {
- Byte = 1,
- Ascii,
- Short,
- Long,
- Rational,
- SByte,
- Undefined,
- SShort,
- SLong,
- SRational,
- Float,
- Double,
- Ifd // TIFF-EP - TIFF PageMaker TechnicalNote 2
- }
-
- public class Tag {
- public ushort Id;
- public EntryType Type;
- public int Count;
- public string Name;
- public string Description;
- }
-
- public class CanonTag : Tag {
- // http://www.gvsoft.homedns.org/exif/makernote-canon.html
-
- public enum CanonId {
- Unknown1 = 0x0000,
- CameraSettings1 = 0x0001,
- Unknown2 = 0x0003,
- CameraSettings2 = 0x0004,
- ImageType = 0x0006,
- FirmwareVersion = 0x0007,
- ImageNumber = 0x0008,
- OwnerName = 0x0009,
- Unknown3 = 0x000a,
- CameraSerialNumber = 0x000c,
- Unknown4 = 0x000d,
- CustomFunctions = 0x000f
- }
-
- public CanonTag (CanonId id, EntryType type, int count, string name, string description)
- {
- this.Id = (ushort)id;
- this.Type = type;
- this.Count = count;
- this.Name = name;
- this.Description = description;
- }
-
- public static System.Collections.Hashtable Tags;
-
- static CanonTag () {
- CanonTag [] tags = {
- new CanonTag (CanonId.Unknown1, EntryType.Short, 6, null, null),
- new CanonTag (CanonId.CameraSettings1, EntryType.Short, -1, "Camera Settings 1", "First Canon MakerNote settings section"),
- new CanonTag (CanonId.Unknown2, EntryType.Short, 4, null, null),
- new CanonTag (CanonId.CameraSettings2, EntryType.Short, -1, "Camera Settings 2", "Second Canon MakerNote settings section"),
- new CanonTag (CanonId.ImageType, EntryType.Ascii, 32, "Image Type", null), // FIXME description
- new CanonTag (CanonId.FirmwareVersion, EntryType.Ascii, 24, "Firmware Version", "Version of the firmware installed on the camera"),
- new CanonTag (CanonId.ImageNumber, EntryType.Long, 1, "Image Number", null), // FIXME description
- new CanonTag (CanonId.OwnerName, EntryType.Long, 32, "Owner Name", "Name of the Camera Owner"), // FIXME description
- new CanonTag (CanonId.Unknown4, EntryType.Short, -1, null, null),
- new CanonTag (CanonId.CameraSerialNumber, EntryType.Short, 1, "Serial Number", null), //FIXME description
- new CanonTag (CanonId.Unknown4, EntryType.Short, -1, null, null),
- new CanonTag (CanonId.CustomFunctions, EntryType.Short, -1, "Custom Functions", "Camera Custom Functions")
- };
-
- foreach (CanonTag tag in tags)
- Tags [tag.Id] = tag;
- }
-
- }
-
- public enum Endian {
- Big,
- Little
- }
-
- public class ParseException : System.Exception
- {
- public ParseException (string msg) : base (msg)
- {
- }
- }
-
- public class ShortReadException : ParseException
- {
- public ShortReadException () : base ("Short Read")
- {
- }
- }
-
- public class Converter {
- public static uint ReadUInt (System.IO.Stream stream, Endian endian)
- {
- byte [] tmp = new byte [4];
-
- if (stream.Read (tmp, 0, tmp.Length) < 4) {
- throw new ShortReadException ();
- }
- return BitConverter.ToUInt32 (tmp, 0, endian == Endian.Little);
- }
-
- public static ushort ReadUShort (System.IO.Stream stream, Endian endian)
- {
- byte [] tmp = new byte [2];
-
- if (stream.Read (tmp, 0, tmp.Length) < 2) {
- throw new ShortReadException ();
- }
-
- return BitConverter.ToUInt16 (tmp, 0, endian == Endian.Little);
- }
- }
-
- public class Header : SemWeb.StatementSource {
- public Endian endian;
-
- private uint directory_offset;
- public ImageDirectory Directory;
-
- // false seems a safe default
- public bool Distinct {
- get { return false; }
- }
-
- public Header (System.IO.Stream stream)
- {
- //using (new Timer ("new Tiff.Header")) {
- byte [] data = new byte [8];
- stream.Read (data, 0, data.Length);
- if (data [0] == 'M' && data [1] == 'M')
- endian = Endian.Big;
- else if (data [0] == 'I' && data [1] == 'I')
- endian = Endian.Little;
-
- ushort marker = BitConverter.ToUInt16 (data, 2, endian == Endian.Little);
- switch (marker) {
- case 42:
- //System.Console.WriteLine ("Found Standard Tiff Marker {0}", marker);
- break;
- case 0x4f52:
- Log.DebugFormat ("Found Olympus Tiff Marker {0}", marker.ToString ("x"));
- break;
- case 0x4e31:
- Log.DebugFormat ("Found Navy Interchange File Format Tiff Marker {0}", marker.ToString ("x"));
- break;
- default:
- Log.DebugFormat ("Found Unknown Tiff Marker {0}", marker.ToString ("x"));
- break;
- }
-
- //System.Console.WriteLine ("Converting Something");
- directory_offset = BitConverter.ToUInt32 (data, 4, endian == Endian.Little);
-
- if (directory_offset < 8)
- throw new ParseException ("Invalid IFD0 Offset [" + directory_offset.ToString () + "]");
-
- Directory = new ImageDirectory (stream, directory_offset, endian);
- //}
- }
-
-
- public void Select (SemWeb.StatementSink sink)
- {
- //using (new Timer ("Tiff.Header.Select")) {
- SelectDirectory (Directory, sink);
- //}
- }
-
- public void SelectDirectory (ImageDirectory dir, StatementSink sink)
- {
- foreach (DirectoryEntry e in dir.Entries) {
- switch (e.Id) {
- case TagId.IPTCNAA:
- System.IO.Stream iptcstream = new System.IO.MemoryStream (e.RawData);
- FSpot.Imaging.Iptc.IptcFile iptc = new FSpot.Imaging.Iptc.IptcFile (iptcstream);
- iptc.Select (sink);
- break;
- case TagId.PhotoshopPrivate:
- System.IO.Stream bimstream = new System.IO.MemoryStream (e.RawData);
- FSpot.Imaging.Bim.BimFile bim = new FSpot.Imaging.Bim.BimFile (bimstream);
- bim.Select (sink);
- break;
- case TagId.ImageDescription:
- MetadataStore.AddLiteral (sink, "dc:description", "rdf:Alt",
- new SemWeb.Literal (e.ValueAsString [0], "x-default", null));
- break;
- case TagId.UserComment:
- MetadataStore.AddLiteral (sink, "exif:UserComment", "rdf:Alt",
- new SemWeb.Literal (e.ValueAsString [0], "x-default", null));
- break;
- case TagId.Copyright:
- MetadataStore.AddLiteral (sink, "dc:rights", "rdf:Alt",
- new SemWeb.Literal (e.ValueAsString [0], "x-default", null));
- break;
- case TagId.Artist:
- MetadataStore.Add (sink, "dc:creator", "rdf:Seq", e.ValueAsString);
- break;
- case TagId.ExifIfdPointer:
- try {
- ImageDirectory sub = ((SubdirectoryEntry)e).Directory [0];
- SelectDirectory (sub, sink);
- } catch (System.Exception ex) {
- Log.Exception (ex);
- }
- break;
- case TagId.Software:
- MetadataStore.AddLiteral (sink, "xmp:CreatorTool", e.ValueAsString [0]);
- break;
- case TagId.DateTime:
- try {
-
- MetadataStore.AddLiteral (sink, "xmp:ModifyDate",
- e.ValueAsDate.ToString ("yyyy-MM-ddThh:mm:ss"));
- } catch (System.Exception ex) {
- Log.ErrorFormat ("error parsing {0}{2}{1}", e.ValueAsString[0], ex, Environment.NewLine);
- }
-
- break;
- case TagId.DateTimeOriginal:
- case TagId.DateTimeDigitized:
- // FIXME subsectime needs to be included in these values
- // FIXME shouldn't DateTimeOriginal be xmp:CreateDate? the spec says no but wtf?
- try {
- MetadataStore.AddLiteral (sink, "exif:" + e.Id.ToString (),
- e.ValueAsDate.ToString ("yyyy-MM-ddThh:mm:ss"));
- } catch (System.Exception ex) {
- Log.ErrorFormat ("error parsing {0}{2}{1}", e.ValueAsString[0], ex, Environment.NewLine);
- }
- break;
- //case TagId.SpatialFrequencyResponse
- case TagId.ExifCFAPattern:
- CFAPattern pattern = new CFAPattern (e.RawData, e.IsLittle);
- Entity empty = new BNode ();
- Statement top = new Statement (MetadataStore.FSpotXMPBase,
- (Entity)MetadataStore.Namespaces.Resolve ("exif:" + e.Id.ToString ()),
- empty);
-
- Statement cols = new Statement (empty,
- (Entity) MetadataStore.Namespaces.Resolve ("exif:Columns"),
- new SemWeb.Literal (pattern.Columns.ToString (), null, null));
- sink.Add (cols);
- Statement rows = new Statement (empty,
- (Entity) MetadataStore.Namespaces.Resolve ("exif:Rows"),
- new SemWeb.Literal (pattern.Rows.ToString (), null, null));
- sink.Add (rows);
- string [] vals = e.ArrayToString (pattern.Values);
- MetadataStore.Add (sink, empty, "exif:Values", "rdf:Seq", vals);
- sink.Add (top);
- break;
- case TagId.ExifVersion:
- case TagId.FlashPixVersion:
- case TagId.ColorSpace:
- case TagId.CompressedBitsPerPixel:
- case TagId.PixelYDimension:
- case TagId.PixelXDimension:
- case TagId.RelatedSoundFile:
- case TagId.ExposureTime:
- case TagId.FNumber:
- case TagId.ExposureProgram:
- case TagId.SpectralSensitivity:
- case TagId.ShutterSpeedValue:
- case TagId.ApertureValue:
- case TagId.BrightnessValue:
- case TagId.ExposureBiasValue:
- case TagId.MaxApertureValue:
- case TagId.SubjectDistance:
- case TagId.MeteringMode:
- case TagId.LightSource:
- case TagId.FocalLength:
- case TagId.FlashEnergy:
- case TagId.FocalPlaneXResolution:
- case TagId.FocalPlaneYResolution:
- case TagId.FocalPlaneResolutionUnit:
- case TagId.ExposureIndex:
- case TagId.SensingMethod:
- case TagId.FileSource:
- case TagId.SceneType:
- case TagId.CustomRendered:
- case TagId.ExposureMode:
- case TagId.WhiteBalance:
- case TagId.DigitalZoomRatio:
- case TagId.FocalLengthIn35mmFilm:
- case TagId.SceneCaptureType:
- case TagId.GainControl:
- case TagId.Contrast:
- case TagId.Saturation:
- case TagId.Sharpness:
- MetadataStore.AddLiteral (sink, "exif:" + e.Id.ToString (), e.ValueAsString [0]);
- break;
- case TagId.ComponentsConfiguration:
- case TagId.ISOSpeedRatings:
- case TagId.SubjectArea:
- case TagId.SubjectLocation:
- MetadataStore.Add (sink, "exif:" + e.Id.ToString (), "rdf:Seq", e.ValueAsString);
- break;
- case TagId.TransferFunction:
- case TagId.YCbCrSubSampling:
- case TagId.WhitePoint:
- case TagId.PrimaryChromaticities:
- case TagId.YCbCrCoefficients:
- case TagId.ReferenceBlackWhite:
- case TagId.BitsPerSample:
- MetadataStore.Add (sink, "tiff:" + e.Id.ToString (), "rdf:Seq", e.ValueAsString);
- break;
- case TagId.Compression:
- case TagId.PhotometricInterpretation:
- case TagId.SamplesPerPixel:
- case TagId.PlanarConfiguration:
- case TagId.YCbCrPositioning:
- case TagId.ResolutionUnit:
- case TagId.ImageWidth:
- case TagId.ImageLength:
- case TagId.Model:
- case TagId.Make:
- try {
- MetadataStore.AddLiteral (sink, "tiff:" + e.Id.ToString (), e.ValueAsString [0]);
- } catch (System.Exception ex) {
- Log.ErrorFormat ("error parsing {0}{2}{1}", e.Id, ex, Environment.NewLine);
- }
- break;
- }
- }
- }
- }
-
- public class ImageDirectory {
- protected Endian endian;
- protected ushort num_entries;
- protected List<DirectoryEntry> entries;
- protected uint orig_position;
-
- protected uint next_directory_offset;
- ImageDirectory next_directory;
-
- protected bool has_header;
- protected bool has_footer;
-
- public ImageDirectory (System.IO.Stream stream, uint start_position, Endian endian)
- {
- this.endian = endian;
- orig_position = start_position;
- Load (stream);
- }
-
- protected void Load (System.IO.Stream stream)
- {
- ReadHeader (stream);
- ReadEntries (stream);
- ReadFooter (stream);
-
- LoadEntries (stream);
- LoadNextDirectory (stream);
- }
-
- public virtual bool ReadHeader (System.IO.Stream stream)
- {
- stream.Seek ((long)orig_position, System.IO.SeekOrigin.Begin);
- return true;
- }
-
- protected virtual void ReadEntries (System.IO.Stream stream)
- {
- num_entries = Converter.ReadUShort (stream, endian);
- entries = new List<DirectoryEntry> (num_entries);
- int entry_length = num_entries * 12;
- byte [] content = new byte [entry_length];
-
- if (stream.Read (content, 0, content.Length) < content.Length) {
- throw new ShortReadException ();
- }
-
-
- for (int pos = 0; pos < entry_length; pos += 12) {
- DirectoryEntry entry = CreateEntry (this, content, pos, this.endian);
- entries.Add (entry);
- if (entry.Id == TagId.NewSubfileType) {
-
- }
- }
- }
-
- protected virtual void ReadFooter (System.IO.Stream stream)
- {
- next_directory_offset = Converter.ReadUInt (stream, this.endian);
- }
-
- protected void LoadEntries (System.IO.Stream stream)
- {
- foreach (DirectoryEntry entry in entries) {
- entry.LoadExternal (stream);
- }
- }
-
- protected void LoadNextDirectory (System.IO.Stream stream)
- {
- next_directory = null;
- try {
- if (next_directory_offset != 0 && next_directory_offset != orig_position)
- next_directory = new ImageDirectory (stream, next_directory_offset, this.endian);
-
- } catch (System.Exception) {
- //System.Console.WriteLine ("Error loading directory {0}", e.ToString ());
- next_directory = null;
- next_directory_offset = 0;
- }
- }
-
- public ImageDirectory NextDirectory {
- get {
- return next_directory;
- }
- }
-
- public List<DirectoryEntry> Entries {
- get {
- return entries;
- }
- }
-
- public DirectoryEntry Lookup (TagId id)
- {
- foreach (DirectoryEntry entry in entries)
- if (entry.Id == id)
- return entry;
-
-
- return null;
- }
-
- public DirectoryEntry Lookup (uint id)
- {
- foreach (DirectoryEntry entry in entries)
- if ((uint)entry.Id == id)
- return entry;
-
- return null;
- }
-
- public static DirectoryEntry CreateEntry (ImageDirectory parent, byte [] input, int start, Endian header_endian)
- {
- TagId tagid;
- EntryType type;
-
- DirectoryEntry.ParseHeader (input, start, out tagid, out type, header_endian);
- //ConstructorFunc ctor = ctors[tagid];
- //if (ctor == null) {
- // return ctor (input, header_endian);
- //}
-
- switch (tagid) {
- case TagId.ExifIfdPointer:
- case TagId.GPSInfoIfdPointer:
- case TagId.InteroperabilityIfdPointer:
- case TagId.SubIFDs:
- return new SubdirectoryEntry (input, start, header_endian);
- //case TagId.MakerNote:
- //return new MakerNoteEntry (input, start, header_endian);
- //case TagId.PimIfdPointer:
- //return new
- //case TagId.MakerNote:
- //return new MakerNoteEntry (input, start, header_endian);
- }
-
- switch (type) {
- case EntryType.Ifd:
- //System.Console.WriteLine ("Trying to load {0} {1}", tagid, tagid.ToString ("x"));
- return new SubdirectoryEntry (input, start, header_endian);
- case EntryType.Byte:
- return new ByteEntry (input, start, header_endian);
- case EntryType.Long:
- return new LongEntry (input, start, header_endian);
- case EntryType.Short:
- return new ShortEntry (input, start, header_endian);
- }
-
- return new DirectoryEntry (input, start, header_endian);
- }
-
+ /*
public Cms.Profile GetProfile ()
{
Cms.ColorCIExyY whitepoint = new Cms.ColorCIExyY (0, 0, 0);
@@ -1310,527 +98,33 @@ namespace FSpot.Imaging.Tiff {
return new Cms.Profile (whitepoint, primaries, transfer);
}
+ }*/
- public void Dump (string name)
- {
- Log.DebugFormat ("Starting {0}", name);
- foreach (DirectoryEntry e in this.Entries)
- e.Dump (name);
- Log.DebugFormat ("Ending {0}", name);
- }
-
- public string Dump2 ()
- {
- System.Text.StringBuilder builder = new System.Text.StringBuilder ();
- builder.Append ("Dummping IFD");
- foreach (DirectoryEntry entry in entries) {
- builder.Append (entry.ToString ()+ Environment.NewLine);
-
- if (entry is SubdirectoryEntry)
- builder.Append ("Found SUBDIRECTORYENTRY" + Environment.NewLine);
- }
-
- if (next_directory != null) {
- builder.Append ("Dummping Next IFD");
- builder.Append (next_directory.Dump2 ());
- }
-
- return builder.ToString ();
- }
- }
-
- public class MakerNoteEntry : SubdirectoryEntry {
- public MakerNoteEntry (byte [] data, int offset, Endian endian) : base (data, offset, endian)
- {
-
- }
-
- public override uint GetEntryCount ()
- {
- return 1;
- }
-
- public override void LoadExternal (System.IO.Stream stream)
- {
- }
- }
-
-
- public class SubdirectoryEntry : DirectoryEntry {
- public uint directory_offset;
- public ImageDirectory [] Directory;
-
- public SubdirectoryEntry (byte [] data, int offset, Endian endian) : base (data, offset, endian)
- {
- if (this.GetEntryCount () > 1) {
- Log.DebugFormat ("Count is greater than 1 ({1}) on Subdirectory {0} interesting", tagid, count);
- }
- }
+ public class DngFile : BaseImageFile {
+ uint offset;
- public virtual uint GetEntryCount ()
- {
- return count;
- }
-
- public override void LoadExternal (System.IO.Stream stream)
- {
- uint entry_count = GetEntryCount ();
- Directory = new ImageDirectory [entry_count];
-
- base.LoadExternal (stream);
-
- for (int i = 0; i < entry_count; i++) {
- try {
- directory_offset = BitConverter.ToUInt32 (raw_data, i * 4, endian == Endian.Little);
- if (directory_offset == offset_origin + 8)
- throw new Exception ("recursive ifd");
- Directory [i] = new ImageDirectory (stream, directory_offset, endian);
- } catch (System.Exception e) {
- Log.ErrorFormat ("Error loading Subdirectory {0} at {2}: {3}{1}",
- this.Id, e, directory_offset, Environment.NewLine);
- }
-
- }
- }
-
- public override void Dump (string name)
- {
- for (int i = 0; i < GetEntryCount (); i++) {
- string subdirname = System.String.Format ("{0}{1}[{2}]({3})]", name, tagid, i, directory_offset);
-
- try {
- if (Directory [i] != null)
- Directory [i].Dump (subdirname);
- } catch (System.Exception e) {
- Log.Exception (e);
- }
- }
- }
- }
-
- public class ShortEntry : DirectoryEntry {
- public ShortEntry (byte [] data, int offset, Endian endian) : base (data, offset, endian)
- {
- }
- }
-
- public class LongEntry : DirectoryEntry {
- public LongEntry (byte [] data, int offset, Endian endian) : base (data, offset, endian)
- {
- if (type != EntryType.Long)
- throw new ParseException (System.String.Format ("Invalid Settings At Birth {0}", tagid));
- }
- }
-
- public class ByteEntry : DirectoryEntry {
- public ByteEntry (byte [] data, int offset, Endian endian) : base (data, offset, endian)
- {
- if (type != EntryType.Byte)
- throw new ParseException ("Invalid Settings At Birth");
- }
- }
-
-#if false
- public class ImageLoader {
- int width;
- int length;
- int [] bps;
- PhotometricInterpretation interpretation;
- Compression compression;
- uint [] offsets;
- uint [] strip_byte_counts;
- uint rows_per_strip;
- byte [] strip;
-
- public ImageLoader (ImageDirectory directory)
- {
- width = directory.Lookup (TagId.ImageWidth).ValueAsLong [0];
- length = directory.Lookup (TagId.ImageLength).ValueAsLong [0];
- bps = directory.Lookup (TagId.BitsPerSample).ValueAsLong;
-
- compression = (Compression) directory.Lookup (TagId.Compression).ValueAsLong [0];
- interpretation = (PhotometricInterpretation) directory.Lookup (TagId.PhotometricInterpretation).ValueAsLong [0];
-
- offsets = directory.Lookup (TagId.StripOffsets).ValueAsLong;
- strip_byte_counts = directory.Lookup (TagId.StripByteCounts).ValueAsLong;
- rows_per_strip = directory.Lookup (TagId.RowsPerStrip).ValueAsLong [0];
-
- if (interpretation !=
- }
-
-
- public Gdk.Pixbuf LoadPixbuf (System.IO.Stream stream)
- {
- Gdk.Pixbuf dest = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, width, height);
- strip = new byte [strip_byte_counts];
- int row;
- for (int i = 0; i < offsets.Length; i++) {
- strip = new byte [strip_byte_counts [i]];
- stream.Read (strip, 0, strip.Length);
- switch (compression) {
- case Compression.Notice
-
- }
- }
- }
- }
-#endif
-
- public class DirectoryEntry {
- protected TagId tagid;
- protected EntryType type;
- protected uint count;
- protected uint offset_origin;
- protected uint data_offset;
-
- protected byte [] raw_data;
- protected Endian endian;
-
- public TagId Id {
- get {
- return tagid;
- }
- }
-
- public EntryType Type {
- get {
- return type;
- }
- }
-
- public uint Count {
- get {
- return count;
- }
- }
-
- public void SetOrigin (uint pos)
- {
- offset_origin = pos;
- }
-
- public uint Position {
- get {
- return offset_origin + data_offset;
- }
- }
-
- public uint Length {
- get { return (uint)(Count * GetTypeSize ()); }
- }
-
- public virtual int GetTypeSize ()
- {
- return GetTypeSize (type);
- }
-
- public static int GetTypeSize (EntryType type)
- {
- switch (type) {
- case EntryType.Byte:
- case EntryType.SByte:
- case EntryType.Undefined:
- case EntryType.Ascii:
- return 1;
- case EntryType.Short:
- case EntryType.SShort:
- return 2;
- case EntryType.Long:
- case EntryType.SLong:
- case EntryType.Float:
- return 4;
- case EntryType.Double:
- case EntryType.Rational:
- case EntryType.SRational:
- return 8;
- default:
- return 1;
- }
- }
-
- public bool IsLittle {
- get {
- return (endian == Endian.Little);
- }
- }
-
- public static int ParseHeader (byte [] data, int start, out TagId tagid, out EntryType type, Endian endian)
- {
- tagid = (TagId) BitConverter.ToUInt16 (data, start, endian == Endian.Little);
- type = (EntryType) BitConverter.ToUInt16 (data, start + 2, endian == Endian.Little);
- return 4;
- }
-
- public DirectoryEntry (byte [] data, int start, Endian endian)
- {
- this.endian = endian;
-
- start += ParseHeader (data, start, out this.tagid, out this.type, endian);
- ParseStream (data, start);
- }
-
- public virtual void LoadExternal (System.IO.Stream stream)
- {
- if (data_offset != 0) {
- stream.Seek ((long)Position, System.IO.SeekOrigin.Begin);
- byte [] data = new byte [count * GetTypeSize ()];
- if (stream.Read (data, 0, data.Length) < data.Length) {
- throw new ShortReadException ();
- }
- raw_data = data;
- }
- }
-
- public virtual void Dump (string name)
- {
- switch (this.Type) {
- case EntryType.Short:
- case EntryType.Long:
- uint [] vals = this.ValueAsLong;
- Log.DebugFormat ("{3}{1}({2}) [{0}] (", vals.Length, this.Id, this.Type, name);
- for (int i = 0; i < System.Math.Min (15, vals.Length); i++) {
- System.Console.Write (" {0}", vals [i]);
- }
- Log.Debug (")");
- break;
- case EntryType.Ascii:
- Log.DebugFormat ("{3}{1}({2}) (\"{0}\")", this.StringValue, this.Id, this.Type, name);
- break;
- default:
- Log.DebugFormat ("{3}{1}({2}) [{0}]", this.Count, this.Id, this.Type, name);
- break;
- }
- }
-
- protected void ParseStream (byte [] data, int start)
- {
- int i = start;
-
- count = BitConverter.ToUInt32 (data, i, endian == Endian.Little);
- i += 4;
- int size = (int)count * GetTypeSize ();
- if (size > 4)
- data_offset = BitConverter.ToUInt32 (data, i, endian == Endian.Little);
- else {
- data_offset = 0;
- raw_data = new byte [size];
- System.Array.Copy (data, i, raw_data, 0, size);
- }
- }
-
- public static System.DateTime DateTimeFromString (string dt)
- {
- // Exif DateTime strings are formatted as
- // "YYYY:MM:DD HH:MM:SS"
-
- string delimiters = " :";
- string[] dt_data = dt.Split ( delimiters.ToCharArray(), 6 );
- System.DateTime result;
- result = new System.DateTime (System.Int32.Parse(dt_data[0]),
- System.Int32.Parse(dt_data[1]),
- System.Int32.Parse(dt_data[2]),
- System.Int32.Parse(dt_data[3]),
- System.Int32.Parse(dt_data[4]),
- System.Int32.Parse(dt_data[5]));
-
- return result;
- }
-
- public byte [] Value {
- get {
- return raw_data;
- }
- }
-
- public byte [] RawData {
- get {
- return raw_data;
- }
- }
-
- public string [] ValueAsString {
- get {
- switch (this.Type) {
- case EntryType.Short:
- case EntryType.Long:
- return ArrayToString (this.ValueAsLong);
- case EntryType.Rational:
- return ArrayToString (this.RationalValue);
- case EntryType.SRational:
- return ArrayToString (this.SRationalValue);
- case EntryType.Undefined:
- switch (Id) {
- case TagId.UserComment:
- return new string [] { UserCommentValue };
- case TagId.FlashPixVersion:
- case TagId.ExifVersion:
- return new string [] { StringValue };
- case TagId.FileSource:
- case TagId.SceneType:
- return ArrayToString (this.RawData);
- case TagId.ComponentsConfiguration:
- return ArrayToString (ValueAsLong);
- default:
- Log.DebugFormat ("Cannot convert type \"{0}\" to string", Id);
- break;
- }
- break;
- case EntryType.Ascii:
- return StringValue.Split ('\0');
- }
- return null;
- }
- }
-
- public string [] ArrayToString (System.Array array)
+ public DngFile (SafeUri uri) : base (uri)
{
- string [] vals = new string [array.Length];
- for (int i = 0; i < array.Length; i++)
- vals [i] = array.GetValue (i).ToString ();
-
- return vals;
- }
-
- public uint [] ValueAsLong {
- get {
- uint [] data = new uint [this.Count];
- for (int i = 0; i < this.Count; i++) {
- switch (this.Type) {
- case EntryType.Long:
- data [i] = BitConverter.ToUInt32 (raw_data, i * GetTypeSize (), endian == Endian.Little);
- break;
- case EntryType.Short:
- data [i] = BitConverter.ToUInt16 (raw_data, i * GetTypeSize (), endian == Endian.Little);
- break;
- case EntryType.Undefined:
- case EntryType.Byte:
- data [i] = raw_data [i];
- break;
- default:
- throw new ParseException ("Invalid conversion");
- }
- }
- return data;
- }
- }
-
- // The following methods are usded to convert the data
- // to the various type regardless of the entry
- // type, they are used internally in processing the data
- // Use at your own risk.
-
- public string StringValue {
- get {
- return System.Text.Encoding.ASCII.GetString (raw_data);
- }
- }
-
- public System.DateTime ValueAsDate {
- get {
- return DirectoryEntry.DateTimeFromString (StringValue);
- }
- }
-
- public string UserCommentValue {
- get {
- UserComment comment = new UserComment (raw_data, IsLittle);
- return comment.Value;
- }
- }
-
- public SRational [] SRationalValue {
- get {
- Rational [] vals = RationalValue;
- SRational [] data = new SRational [vals.Length];
-
- for (int i = 0; i < vals.Length; i++)
- data [i] = SRational.BitwiseCopy (vals [i]);
-
- return data;
- }
}
- public Rational [] RationalValue {
- get {
- uint [] vals = LongValue;
- Rational [] data = new Rational [vals.Length / 2];
-
- for (int i = 0; i < vals.Length; i += 2)
- data [i/2] = new Rational (vals [i], vals [i + 1]);
-
- return data;
- }
-
- }
-
- public uint [] LongValue {
- get {
- uint [] data = new uint [raw_data.Length / 4];
- for (int i = 0; i < raw_data.Length; i+= 4)
- data [i/4] = BitConverter.ToUInt32 (raw_data, i, endian == Endian.Little);
-
- return data;
- }
- }
-
- public ushort [] ShortValue {
- get {
- ushort [] data = new ushort [raw_data.Length];
- for (int i = 0; i < raw_data.Length; i+= 2) {
- data [i] = BitConverter.ToUInt16 (raw_data, i, endian == Endian.Little);
- }
- return data;
- }
- }
- }
-
-
- public class TiffFile : BaseImageFile, SemWeb.StatementSource {
- public Header Header;
-
- // false seems a safe default
- public bool Distinct {
- get { return false; }
- }
-
- public TiffFile (SafeUri uri) : base (uri)
+ protected override void ExtractMetadata (TagLib.Image.File metadata)
{
try {
- using (System.IO.Stream input = PixbufStream ()) {
- this.Header = new Header (input);
- }
- } catch (System.Exception e) {
- Log.Error (e.ToString ());
+ var tag = metadata.GetTag (TagTypes.TiffIFD) as IFDTag;
+ var structure = tag.Structure;
+ var sub_entries = (structure.GetEntry (0, (ushort) IFDEntryTag.SubIFDs) as SubIFDArrayEntry).Entries;
+ var subimage_structure = sub_entries [sub_entries.Length - 1];
+ var entry = subimage_structure.GetEntry (0, (ushort) IFDEntryTag.StripOffsets);
+ offset = (entry as StripOffsetsIFDEntry).Values [0];
+ } catch (Exception e) {
+ Log.DebugException (e);
}
- }
-
- public virtual void Select (SemWeb.StatementSink sink)
- {
- Header.SelectDirectory (Header.Directory, sink);
- }
-
- public System.IO.Stream LookupJpegSubstream (ImageDirectory directory)
- {
- uint offset = directory.Lookup (TagId.JPEGInterchangeFormat).ValueAsLong [0];
-
- System.IO.Stream file = PixbufStream ();
- file.Position = offset;
- return file;
- }
- }
-
- public class DngFile : TiffFile {
- public DngFile (SafeUri uri) : base (uri)
- {
+ base.ExtractMetadata (metadata);
}
public override System.IO.Stream PixbufStream ()
{
try {
- SubdirectoryEntry sub = (SubdirectoryEntry) Header.Directory.Lookup (TagId.SubIFDs);
- ImageDirectory directory = sub.Directory [sub.Directory.Length - 1];
-
- uint offset = directory.Lookup (TagId.StripOffsets).ValueAsLong [0];
System.IO.Stream file = base.PixbufStream ();
file.Position = offset;
return file;
@@ -1838,117 +132,63 @@ namespace FSpot.Imaging.Tiff {
return DCRawFile.RawPixbufStream (Uri);
}
}
-
- public override void Select (SemWeb.StatementSink sink)
- {
-
- /* this is just a sanity pass, if the first ifd is not a subfile use the normal
- * tiff path
- */
- DirectoryEntry e = Header.Directory.Lookup (TagId.NewSubfileType);
- if (e == null) {
- base.Select (sink);
- return;
- }
-
- /*
- * Ifd0 will also have the exif directory
- */
- ImageDirectory dir = Header.Directory;
- SubdirectoryEntry sub = (SubdirectoryEntry) dir.Lookup (TagId.ExifIfdPointer);
- if (sub != null)
- Header.SelectDirectory (sub.Directory [0], sink);
-
- /*
- * now we lookup subifd0 (we should probably scan the newsubfile types here)
- * and load the metadata we are interested in from it.
- */
- sub = (SubdirectoryEntry) Header.Directory.Lookup (TagId.SubIFDs);
-
- if (e == null)
- e = dir.Lookup (TagId.NewSubfileType);
-
- int i = 0;
- do {
- uint dirtype = e.ValueAsLong [0];
- if (dirtype == 0) {
- Header.SelectDirectory (dir, sink);
- break;
- }
-
- if (sub == null)
- break;
-
- dir = sub.Directory [i];
- e = dir.Lookup (TagId.NewSubfileType);
- i++;
- } while (i < sub.Directory.Length);
-
-
- }
}
- public class NefFile : TiffFile {
+ public class NefFile : BaseImageFile {
+ byte [] jpeg_data;
+
public NefFile (SafeUri uri) : base (uri)
{
}
- public override void Select (SemWeb.StatementSink sink)
+ protected override void ExtractMetadata (TagLib.Image.File metadata)
{
- DirectoryEntry e = Header.Directory.Lookup (TagId.NewSubfileType);
-
- if (e == null) {
- base.Select (sink);
- return;
+ try {
+ var tag = metadata.GetTag (TagTypes.TiffIFD) as IFDTag;
+ var structure = tag.Structure;
+ var SubImage1_structure = (structure.GetEntry (0, (ushort) IFDEntryTag.SubIFDs) as SubIFDArrayEntry).Entries [0];
+ var entry = SubImage1_structure.GetEntry (0, (ushort) IFDEntryTag.JPEGInterchangeFormat);
+ jpeg_data = (entry as ThumbnailDataIFDEntry).Data.Data;
+ } catch (Exception e) {
+ Log.DebugException (e);
+ jpeg_data = null;
}
-
- ImageDirectory dir = Header.Directory;
- SubdirectoryEntry sub = (SubdirectoryEntry) dir.Lookup (TagId.ExifIfdPointer);
-
- if (sub != null)
- Header.SelectDirectory (sub.Directory [0], sink);
-
- sub = (SubdirectoryEntry) Header.Directory.Lookup (TagId.SubIFDs);
-
- int i = 0;
- do {
- uint dirtype = e.ValueAsLong [0];
- if (dirtype == 0) {
- Header.SelectDirectory (dir, sink);
- break;
- }
-
- if (sub == null)
- break;
-
- dir = sub.Directory [i];
- if (dir != null)
- e = dir.Lookup (TagId.NewSubfileType);
- i++;
- } while (i < sub.Directory.Length);
+ base.ExtractMetadata (metadata);
}
public override System.IO.Stream PixbufStream ()
{
- try {
- SubdirectoryEntry sub = (SubdirectoryEntry) Header.Directory.Lookup (TagId.SubIFDs);
- ImageDirectory jpeg_directory = sub.Directory [0];
- return LookupJpegSubstream (jpeg_directory);
- } catch (System.Exception) {
+ if (jpeg_data != null) {
+ return new MemoryStream (jpeg_data);
+ } else {
return DCRawFile.RawPixbufStream (Uri);
}
}
}
- public class Cr2File : TiffFile {
+ public class Cr2File : BaseImageFile {
+ uint offset;
+
public Cr2File (SafeUri uri) : base (uri)
{
}
+ protected override void ExtractMetadata (TagLib.Image.File metadata)
+ {
+ try {
+ var tag = metadata.GetTag (TagTypes.TiffIFD) as IFDTag;
+ var structure = tag.Structure;
+ var entry = structure.GetEntry (0, (ushort) IFDEntryTag.StripOffsets);
+ offset = (entry as StripOffsetsIFDEntry).Values [0];
+ } catch (Exception e) {
+ Log.DebugException (e);
+ }
+ base.ExtractMetadata (metadata);
+ }
+
public override System.IO.Stream PixbufStream ()
{
- uint offset = Header.Directory.Lookup (TagId.StripOffsets).ValueAsLong [0];
System.IO.Stream file = base.PixbufStream ();
file.Position = offset;
return file;
diff --git a/src/MetadataStore.cs b/src/MetadataStore.cs
index 78dba8d..ac3fbf1 100644
--- a/src/MetadataStore.cs
+++ b/src/MetadataStore.cs
@@ -21,59 +21,6 @@ namespace FSpot {
new Description ("dc:title", Catalog.GetString ("Title")),
new Description ("dc:rights", Catalog.GetString ("Copyright")),
new Description ("dc:subject", Catalog.GetString ("Subject and Keywords")),
- new Description ("tiff:Compression", Catalog.GetString ("Compression"),
- typeof (FSpot.Imaging.Tiff.Compression)),
- /* Translators: Planar Configuration is the label for the tiff:PlanarConfiguration tag
- "when Planar Configuration=1, this implies that all components must have
- the same BitsPerSample value; when Planar Configuration=2, different
- components could have different bit depths." */
- new Description ("tiff:PlanarConfiguration", Catalog.GetString ("Planar Configuration"),
- typeof (FSpot.Imaging.Tiff.PlanarConfiguration)),
- new Description ("tiff:Orientation", Catalog.GetString ("Orientation"),
- typeof (TagLib.Image.ImageOrientation)),
- new Description ("tiff:PhotometricInterpretation", Catalog.GetString ("Photometric Interpretation"),
- typeof (FSpot.Imaging.Tiff.PhotometricInterpretation)),
- new Description ("tiff:ResolutionUnit", Catalog.GetString ("Resolution Unit"),
- typeof (FSpot.Imaging.Tiff.ResolutionUnit)),
- new Description ("exif:ExposureProgram", Catalog.GetString ("Exposure Program"),
- typeof (FSpot.Imaging.Tiff.ExposureProgram)),
- new Description ("exif:MeteringMode", Catalog.GetString ("Metering Mode"),
- typeof (FSpot.Imaging.Tiff.MeteringMode)),
- new Description ("exif:ExposureMode", Catalog.GetString ("Exposure Mode"),
- typeof (FSpot.Imaging.Tiff.ExposureMode)),
- new Description ("exif:CustomRendered", Catalog.GetString ("Custom Rendered"),
- typeof (FSpot.Imaging.Tiff.CustomRendered)),
- new Description ("exif:ComponentsConfiguration", Catalog.GetString ("Components Configuration"),
- typeof (FSpot.Imaging.Tiff.ComponentsConfiguration)),
- new Description ("exif:LightSource", Catalog.GetString ("Light Source"),
- typeof (FSpot.Imaging.Tiff.LightSource)),
- new Description ("exif:SensingMethod", Catalog.GetString ("Sensing Method"),
- typeof (FSpot.Imaging.Tiff.SensingMethod)),
- new Description ("exif:ColorSpace", Catalog.GetString ("Color Space"),
- typeof (FSpot.Imaging.Tiff.ColorSpace)),
- new Description ("exif:WhiteBalance", Catalog.GetString ("White Balance"),
- typeof (FSpot.Imaging.Tiff.WhiteBalance)),
- new Description ("exif:FocalPlaneResolutionUnit", Catalog.GetString ("Focal Plane Resolution Unit"),
- typeof (FSpot.Imaging.Tiff.ResolutionUnit)),
- new Description ("exif:FileSource", Catalog.GetString ("File Source Type"),
- typeof (FSpot.Imaging.Tiff.FileSource)),
- new Description ("exif:SceneCaptureType", Catalog.GetString ("Scene Capture Type"),
- typeof (FSpot.Imaging.Tiff.SceneCaptureType)),
- /* Translators: Gain Control is the label for the exif:GainControl tag
- "This tag indicates the degree of overall image gain adjustment." */
- new Description ("exif:GainControl", Catalog.GetString ("Gain Control"),
- typeof (FSpot.Imaging.Tiff.GainControl)),
- new Description ("exif:Contrast", Catalog.GetString ("Contrast"),
- typeof (FSpot.Imaging.Tiff.Contrast)),
- new Description ("exif:Saturation", Catalog.GetString ("Saturation"),
- typeof (FSpot.Imaging.Tiff.Saturation)),
- new Description ("exif:Sharpness", Catalog.GetString ("Sharpness"),
- typeof (FSpot.Imaging.Tiff.Sharpness)),
- new Description ("exif:SceneType", Catalog.GetString ("Scene Type"),
- typeof (FSpot.Imaging.Tiff.SceneType))
-
-
-
};
table = new System.Collections.Hashtable ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]