public virtual void Extract(SequentialReader reader, Com.Drew.Metadata.Metadata metadata)
		{
			Com.Drew.Metadata.Directory directory = metadata.GetOrCreateDirectory<AdobeJpegDirectory>();
			try
			{
				reader.SetMotorolaByteOrder(false);
				if (!reader.GetString(5).Equals("Adobe"))
				{
					directory.AddError("Invalid Adobe JPEG data header.");
					return;
				}
				directory.SetInt(AdobeJpegDirectory.TagDctEncodeVersion, reader.GetUInt16());
				directory.SetInt(AdobeJpegDirectory.TagApp14Flags0, reader.GetUInt16());
				directory.SetInt(AdobeJpegDirectory.TagApp14Flags1, reader.GetUInt16());
				directory.SetInt(AdobeJpegDirectory.TagColorTransform, reader.GetInt8());
			}
			catch (IOException ex)
			{
				directory.AddError("IO exception processing data: " + ex.Message);
			}
		}
		public virtual void Extract(SequentialReader reader, Com.Drew.Metadata.Metadata metadata)
		{
			GifHeaderDirectory directory = metadata.GetOrCreateDirectory<GifHeaderDirectory>();
			// FILE HEADER
			//
			// 3 - signature: "GIF"
			// 3 - version: either "87a" or "89a"
			//
			// LOGICAL SCREEN DESCRIPTOR
			//
			// 2 - pixel width
			// 2 - pixel height
			// 1 - screen and color map information flags (0 is LSB)
			//       0-2  Size of the global color table
			//       3    Color table sort flag (89a only)
			//       4-6  Color resolution
			//       7    Global color table flag
			// 1 - background color index
			// 1 - pixel aspect ratio
			reader.SetMotorolaByteOrder(false);
			try
			{
				string signature = reader.GetString(3);
				if (!signature.Equals("GIF"))
				{
					directory.AddError("Invalid GIF file signature");
					return;
				}
				string version = reader.GetString(3);
				if (!version.Equals(Gif87aVersionIdentifier) && !version.Equals(Gif89aVersionIdentifier))
				{
					directory.AddError("Unexpected GIF version");
					return;
				}
				directory.SetString(GifHeaderDirectory.TagGifFormatVersion, version);
				directory.SetInt(GifHeaderDirectory.TagImageWidth, reader.GetUInt16());
				directory.SetInt(GifHeaderDirectory.TagImageHeight, reader.GetUInt16());
				short flags = reader.GetUInt8();
				// First three bits = (BPP - 1)
				int colorTableSize = 1 << ((flags & 7) + 1);
				directory.SetInt(GifHeaderDirectory.TagColorTableSize, colorTableSize);
				if (version.Equals(Gif89aVersionIdentifier))
				{
					bool isColorTableSorted = (flags & 8) != 0;
					directory.SetBoolean(GifHeaderDirectory.TagIsColorTableSorted, isColorTableSorted);
				}
				int bitsPerPixel = ((flags & unchecked((int)(0x70))) >> 4) + 1;
				directory.SetInt(GifHeaderDirectory.TagBitsPerPixel, bitsPerPixel);
				bool hasGlobalColorTable = (flags & unchecked((int)(0xf))) != 0;
				directory.SetBoolean(GifHeaderDirectory.TagHasGlobalColorTable, hasGlobalColorTable);
				directory.SetInt(GifHeaderDirectory.TagTransparentColorIndex, reader.GetUInt8());
				int aspectRatioByte = reader.GetUInt8();
				if (aspectRatioByte != 0)
				{
					float pixelAspectRatio = (float)((aspectRatioByte + 15d) / 64d);
					directory.SetFloat(GifHeaderDirectory.TagPixelAspectRatio, pixelAspectRatio);
				}
			}
			catch (IOException)
			{
				directory.AddError("Unable to read BMP header");
			}
		}
		/// <exception cref="System.IO.IOException"/>
		private void ProcessTag(SequentialReader reader, Com.Drew.Metadata.Directory directory, int directoryType, int tagType, int tagByteCount)
		{
			int tagIdentifier = tagType | (directoryType << 8);
			string @string = null;
			switch (tagIdentifier)
			{
				case IptcDirectory.TagApplicationRecordVersion:
				{
					// short
					int shortValue = reader.GetUInt16();
					reader.Skip(tagByteCount - 2);
					directory.SetInt(tagIdentifier, shortValue);
					return;
				}

				case IptcDirectory.TagUrgency:
				{
					// byte
					directory.SetInt(tagIdentifier, reader.GetUInt8());
					reader.Skip(tagByteCount - 1);
					return;
				}

				case IptcDirectory.TagReleaseDate:
				case IptcDirectory.TagDateCreated:
				{
					// Date object
					if (tagByteCount >= 8)
					{
						@string = reader.GetString(tagByteCount);
						try
						{
							int year = System.Convert.ToInt32(Sharpen.Runtime.Substring(@string, 0, 4));
							int month = System.Convert.ToInt32(Sharpen.Runtime.Substring(@string, 4, 6)) - 1;
							int day = System.Convert.ToInt32(Sharpen.Runtime.Substring(@string, 6, 8));
							DateTime date = new Sharpen.GregorianCalendar(year, month, day).GetTime();
							directory.SetDate(tagIdentifier, date);
							return;
						}
						catch (FormatException)
						{
						}
					}
					else
					{
						// fall through and we'll process the 'string' value below
						reader.Skip(tagByteCount);
					}
					goto case IptcDirectory.TagReleaseTime;
				}

				case IptcDirectory.TagReleaseTime:
				case IptcDirectory.TagTimeCreated:
				default:
				{
					break;
				}
			}
			// time...
			// fall through
			// If we haven't returned yet, treat it as a string
			// NOTE that there's a chance we've already loaded the value as a string above, but failed to parse the value
			if (@string == null)
			{
				@string = reader.GetString(tagByteCount, Runtime.GetProperty("file.encoding"));
			}
			// "ISO-8859-1"
			if (directory.ContainsTag(tagIdentifier))
			{
				// this fancy string[] business avoids using an ArrayList for performance reasons
				string[] oldStrings = directory.GetStringArray(tagIdentifier);
				string[] newStrings;
				if (oldStrings == null)
				{
					newStrings = new string[1];
				}
				else
				{
					newStrings = new string[oldStrings.Length + 1];
					System.Array.Copy(oldStrings, 0, newStrings, 0, oldStrings.Length);
				}
				newStrings[newStrings.Length - 1] = @string;
				directory.SetStringArray(tagIdentifier, newStrings);
			}
			else
			{
				directory.SetString(tagIdentifier, @string);
			}
		}