Пример #1
0
        private static double GetExifRational(Tiff.ImageDirectory directory, Tiff.TagId id)
        {
            if (directory == null)
            {
                return(0);
            }

            Tiff.DirectoryEntry entry = directory.Lookup(id);
            if (entry == null)
            {
                return(-1);
            }

            return(entry.RationalValue [0].Value);
        }
Пример #2
0
        private static string GetExifString(Tiff.ImageDirectory directory, Tiff.TagId id)
        {
            if (directory == null)
            {
                return(null);
            }

            Tiff.DirectoryEntry entry = directory.Lookup(id);
            if (entry == null)
            {
                return(null);
            }

            return(entry.ValueAsString [0]);
        }
Пример #3
0
		public void SelectDirectory (ImageDirectory dir, StatementSink sink)
		{
			foreach (DirectoryEntry e in dir.Entries) {
#if DEBUG_LOADER
				System.Console.WriteLine ("{0}", e.Id);
#endif
				switch (e.Id) {
				case TagId.IPTCNAA:
					System.IO.Stream iptcstream = new System.IO.MemoryStream (e.RawData);
					FSpot.Iptc.IptcFile iptc = new FSpot.Iptc.IptcFile (iptcstream);
					iptc.Select (sink);
					break;
				case TagId.PhotoshopPrivate:
					System.IO.Stream bimstream = new System.IO.MemoryStream (e.RawData);
					FSpot.Bim.BimFile bim = new FSpot.Bim.BimFile (bimstream);
					bim.Select (sink);
					break;
				case TagId.XMP:
					System.IO.Stream xmpstream = new System.IO.MemoryStream (e.RawData);
					FSpot.Xmp.XmpFile xmp = new FSpot.Xmp.XmpFile (xmpstream);
					xmp.Select (sink);
					break;
				case TagId.ImageDescription:
					MetadataStore.AddLiteral (sink, "dc:description", "rdf:Alt", 
								  new Literal (e.ValueAsString [0], "x-default", null));
					break;
				case TagId.UserComment:
					MetadataStore.AddLiteral (sink, "exif:UserComment", "rdf:Alt", 
								  new Literal (e.ValueAsString [0], "x-default", null));
					break;
				case TagId.Copyright:
					MetadataStore.AddLiteral (sink, "dc:rights", "rdf:Alt", 
								  new 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 exc) {
						System.Console.WriteLine (exc);
					}
					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) {
						System.Console.WriteLine (String.Format ("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) {
						System.Console.WriteLine (String.Format ("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 Literal (pattern.Columns.ToString (), null, null));
					sink.Add (cols);
					Statement rows = new Statement (empty, 
									(Entity) MetadataStore.Namespaces.Resolve ("exif:Rows"),
									new 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.Orientation:
				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:
					MetadataStore.AddLiteral (sink, "tiff:" + e.Id.ToString (), e.ValueAsString [0]);
					break;
				}
			}
		}
Пример #4
0
		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:
				System.Console.WriteLine ("Found Olympus Tiff Marker {0}", marker.ToString ("x"));
				break;
			case 0x4e31:
				System.Console.WriteLine ("Found Navy Interchange File Format Tiff Marker {0}", marker.ToString ("x")); 
				break;
			default:
				System.Console.WriteLine ("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 () + "]"); 
			
#if DEBUG_LOADER
			System.Console.WriteLine ("Reading First IFD");
#endif
			Directory = new ImageDirectory (stream, directory_offset, endian); 
			//}
		}
Пример #5
0
		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 != 
		}
Пример #6
0
		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);
					Directory [i] = new ImageDirectory (stream, directory_offset, endian);
				} catch (System.Exception e) {
					System.Console.WriteLine ("Error loading Subdirectory {0} at {2} of {3}bytes:{4}{1}", 
								  this.Id, e, directory_offset, stream.Length, Environment.NewLine);
				}
					
			}
		}
Пример #7
0
		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);
		}
Пример #8
0
		protected void LoadNextDirectory (System.IO.Stream stream)
		{
#if DEBUG_LOADER
			System.Console.WriteLine ("start_position = {1} next_directory_offset = {0}",
						  next_directory_offset, orig_position);
#endif
			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;
			}		
		}
Пример #9
0
		internal static void AddTiffDirectoryProperties (FilterTiff filter, ImageDirectory directory)
		{
			foreach (DirectoryEntry e in directory.Entries) {
				switch (e.Id) {
				case TagId.ImageDescription:
					filter.AddProperty (Beagle.Property.New ("exif:ImageDescription", e.ValueAsString [0]));
					break;
				case TagId.Model:
					filter.AddProperty (Beagle.Property.New ("exif:Model", e.ValueAsString [0]));
					break;
				case TagId.UserComment:
					filter.AddProperty (Beagle.Property.New ("exif:UserComment", e.ValueAsString [0]));
					break;
				case TagId.DateTimeOriginal:
					AddDateProperty (filter, "exif:DateTimeOriginal", e.ValueAsString [0]);
					break;
				case TagId.DateTimeDigitized:
					AddDateProperty (filter, "exif:DateTimeDigitized", e.ValueAsString [0]);
					break;
				case TagId.DateTime:
					AddDateProperty (filter, "exif:DateTime", e.ValueAsString [0]);
					break;
				case TagId.PixelXDimension:
					filter.Width = (int) e.ValueAsLong [0];
					//filter.AddProperty (Beagle.Property.NewUnsearched ("exif:PixelXDimension", e.ValueAsString [0]));
					break;
				case TagId.PixelYDimension:
					filter.Height = (int) e.ValueAsLong [0];
					//filter.AddProperty (Beagle.Property.NewUnsearched ("exif:PixelYDimension", e.ValueAsString [0]));
					break;
				case TagId.ImageWidth:
					uint wval = e.ValueAsLong [0];
					if (filter.Width < wval)
						filter.Width = (int) wval;
					break;
				case TagId.ImageLength:
					uint hval = e.ValueAsLong [0];
					if (filter.Height < hval)
						filter.Height = (int) hval;
					break;
				case TagId.ExposureTime:
					filter.AddProperty (Beagle.Property.NewUnsearched ("exif:ExposureTime", e.ValueAsString [0]));
					break;
				case TagId.ISOSpeedRatings:
					filter.AddProperty (Beagle.Property.NewUnsearched ("exif:ISOSpeedRatings", e.ValueAsString [0]));
					break;
				case TagId.FNumber:
					filter.AddProperty (Beagle.Property.NewUnsearched ("exif:FNumber", Math.Round ((e.RationalValue [0]).Value, 1)));
					break;
				case TagId.FocalLength:
					filter.AddProperty (Beagle.Property.NewUnsearched ("exif:FocalLength", e.ValueAsString [0]));
					break;
				case TagId.Flash:
					ushort flash_val = e.ShortValue [0];
					filter.AddProperty (Beagle.Property.NewBool ("exif:Flash", (flash_val & 0x1) == 0x1));
					break;
				case TagId.XMP:
					XmpFile xmp = new XmpFile (new System.IO.MemoryStream (e.RawData));
					filter.AddXmpProperties (xmp);
					break;
				}
			}
		}
Пример #10
0
        private void AddExifProperties(JpegHeader header)
        {
            Tiff.Header ifd = header.GetExifHeader();
            if (ifd == null)
            {
                return;
            }
            //ifd.Dump ("foo"); // Uncomment to debug

            string str;

            Tiff.DirectoryEntry entry;

            // Add IFD 0 properies

            str = GetExifString(ifd.Directory, Tiff.TagId.Model);
            AddProperty(Beagle.Property.New("exif:Model", str));

            str = GetExifString(ifd.Directory, Tiff.TagId.ImageDescription);
            AddProperty(Beagle.Property.New("exif:ImageDescription", str));

            try {
                entry = ifd.Directory.Lookup(Tiff.TagId.DateTime);
                if (entry != null)
                {
                    // Assume datetime stored in the images are local times
                    AddProperty(Beagle.Property.NewDate("exif:DateTime", entry.ValueAsDate.ToUniversalTime()));
                }
            } catch (FormatException) {
                Logger.Log.Debug("EXIF DateTime '{0}' is invalid.", GetExifString(ifd.Directory, Tiff.TagId.DateTime));
            } catch (ArgumentOutOfRangeException) {
                Logger.Log.Debug("EXIF DateTime '{0}' is invalid.", GetExifString(ifd.Directory, Tiff.TagId.DateTime));
            }

            str = GetExifString(ifd.Directory, Tiff.TagId.Copyright);
            AddProperty(Beagle.Property.New("dc:rights", str));

            // Add IFD 1 properties

            Tiff.SubdirectoryEntry subdir = (Tiff.SubdirectoryEntry)ifd.Directory.Lookup(Tiff.TagId.ExifIfdPointer);
            if (subdir == null)
            {
                return;
            }

            Tiff.ImageDirectory exif = subdir.Directory [0];
            if (exif == null)
            {
                return;
            }

            entry = exif.Lookup(Tiff.TagId.UserComment);
            if (entry != null)
            {
                AddProperty(Beagle.Property.New("exif:UserComment", entry.UserCommentValue));
            }

            uint val = 0;

            entry = exif.Lookup(Tiff.TagId.PixelXDimension);
            if (entry != null)
            {
                val = entry.ValueAsLong [0];
            }
            if (val > 0)
            {
                Width = (int)val;
                AddProperty(Beagle.Property.NewUnsearched("exif:PixelXDimension", val));
            }

            val   = 0;
            entry = exif.Lookup(Tiff.TagId.PixelYDimension);
            if (entry != null)
            {
                val = entry.ValueAsLong [0];
            }
            if (val > 0)
            {
                Height = (int)val;
                AddProperty(Beagle.Property.NewUnsearched("exif:PixelYDimension", val));
            }

            str = GetExifString(exif, Tiff.TagId.ISOSpeedRatings);
            AddProperty(Beagle.Property.NewUnsearched("exif:ISOSpeedRatings", str));

            str = GetExifString(exif, Tiff.TagId.ShutterSpeedValue);
            AddProperty(Beagle.Property.NewUnsearched("exif:ShutterSpeedValue", str));

            str = GetExifString(exif, Tiff.TagId.ExposureTime);
            if (!String.IsNullOrEmpty(str))
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:ExposureTime", str + " sec."));
            }

            double rational_val;

            rational_val = GetExifRational(exif, Tiff.TagId.FNumber);
            if (rational_val > 0)
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:FNumber", String.Format("f/{0}", rational_val)));
            }

            rational_val = GetExifRational(exif, Tiff.TagId.ApertureValue);
            if (rational_val > 0)
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:ApertureValue", rational_val));
            }

            rational_val = GetExifRational(exif, Tiff.TagId.FocalLength);
            if (rational_val > 0)
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:FocalLength", String.Format("{0} mm", rational_val)));
            }

            entry = exif.Lookup(Tiff.TagId.Flash);
            if (entry != null)
            {
                ushort flash = entry.ShortValue [0];
                AddProperty(Beagle.Property.NewUnsearched("exif:Flash", GetFlashString(flash)));
            }
        }