public virtual void TestGetOrCreateDirectoryReturnsSameInstance()
		{
			Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
			Com.Drew.Metadata.Directory directory = metadata.GetOrCreateDirectory<ExifSubIFDDirectory>();
			NUnit.Framework.Assert.AreSame(directory, metadata.GetOrCreateDirectory<ExifSubIFDDirectory>());
			NUnit.Framework.Assert.AreNotSame(directory, metadata.GetOrCreateDirectory<IptcDirectory>());
		}
 public override void OnExtracted([NotNull] FilePath file, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] string relativePath)
 {
     base.OnExtracted(file, metadata, relativePath);
     foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
     {
         foreach (Tag tag in directory.GetTags())
         {
             // Only interested in unknown tags (those without names)
             if (tag.HasTagName())
             {
                 continue;
             }
             Dictionary <int?, int?> occurrenceCountByTag = _occurrenceCountByTagByDirectory.Get(directory.GetName());
             if (occurrenceCountByTag == null)
             {
                 occurrenceCountByTag = new Dictionary <int?, int?>();
                 _occurrenceCountByTagByDirectory.Put(directory.GetName(), occurrenceCountByTag);
             }
             int?count = occurrenceCountByTag.Get(tag.GetTagType());
             if (count == null)
             {
                 count = 0;
                 occurrenceCountByTag.Put(tag.GetTagType(), 0);
             }
             occurrenceCountByTag.Put(tag.GetTagType(), (int)count + 1);
         }
     }
 }
示例#3
0
        public virtual void ReadJpegSegments([NotNull] Iterable <sbyte[]> segments, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] JpegSegmentType segmentType)
        {
            int preambleLength = JpegSegmentPreamble.Length;

            // ICC data can be spread across multiple JPEG segments.
            // We concat them together in this buffer for later processing.
            sbyte[] buffer = null;
            foreach (sbyte[] segmentBytes in segments)
            {
                // Skip any segments that do not contain the required preamble
                if (segmentBytes.Length < preambleLength || !Sharpen.Runtime.EqualsIgnoreCase(JpegSegmentPreamble, Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, preambleLength)))
                {
                    continue;
                }
                // NOTE we ignore three bytes here -- are they useful for anything?
                // Grow the buffer
                if (buffer == null)
                {
                    buffer = new sbyte[segmentBytes.Length - 14];
                    // skip the first 14 bytes
                    System.Array.Copy(segmentBytes, 14, buffer, 0, segmentBytes.Length - 14);
                }
                else
                {
                    sbyte[] newBuffer = new sbyte[buffer.Length + segmentBytes.Length - 14];
                    System.Array.Copy(buffer, 0, newBuffer, 0, buffer.Length);
                    System.Array.Copy(segmentBytes, 14, newBuffer, buffer.Length, segmentBytes.Length - 14);
                    buffer = newBuffer;
                }
            }
            if (buffer != null)
            {
                Extract(new ByteArrayReader(buffer), metadata);
            }
        }
 public virtual void TestGetOrCreateDirectoryReturnsSameInstance()
 {
     Com.Drew.Metadata.Metadata  metadata  = new Com.Drew.Metadata.Metadata();
     Com.Drew.Metadata.Directory directory = metadata.GetOrCreateDirectory <ExifSubIFDDirectory>();
     NUnit.Framework.Assert.AreSame(directory, metadata.GetOrCreateDirectory <ExifSubIFDDirectory>());
     NUnit.Framework.Assert.AreNotSame(directory, metadata.GetOrCreateDirectory <IptcDirectory>());
 }
 public override void OnExtracted([NotNull] FilePath file, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] string relativePath)
 {
     base.OnExtracted(file, metadata, relativePath);
     try
     {
         PrintWriter writer = null;
         try
         {
             writer = OpenWriter(file);
             // Build a list of all directories
             IList <Com.Drew.Metadata.Directory> directories = new AList <Com.Drew.Metadata.Directory>();
             foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
             {
                 directories.Add(directory);
             }
             // Sort them by name
             directories.Sort(new _IComparer_235());
             // Write any errors
             if (metadata.HasErrors())
             {
                 foreach (Com.Drew.Metadata.Directory directory_1 in directories)
                 {
                     if (!directory_1.HasErrors())
                     {
                         continue;
                     }
                     foreach (string error in directory_1.GetErrors())
                     {
                         writer.Format("[ERROR: %s] %s\n", directory_1.GetName(), error);
                     }
                 }
                 writer.Write("\n");
             }
             // Write tag values for each directory
             foreach (Com.Drew.Metadata.Directory directory_2 in directories)
             {
                 string directoryName = directory_2.GetName();
                 foreach (Tag tag in directory_2.GetTags())
                 {
                     string tagName     = tag.GetTagName();
                     string description = tag.GetDescription();
                     writer.Format("[%s - %s] %s = %s%n", directoryName, tag.GetTagTypeHex(), tagName, description);
                 }
                 if (directory_2.GetTagCount() != 0)
                 {
                     writer.Write('\n');
                 }
             }
         }
         finally
         {
             CloseWriter(writer);
         }
     }
     catch (IOException e)
     {
         Sharpen.Runtime.PrintStackTrace(e);
     }
 }
		public virtual void TestGetErrors()
		{
			Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
			Sharpen.Tests.IsFalse(metadata.HasErrors());
			ExifSubIFDDirectory directory = metadata.GetOrCreateDirectory<ExifSubIFDDirectory>();
			directory.AddError("Test Error 1");
			Sharpen.Tests.IsTrue(metadata.HasErrors());
		}
        public virtual void TestGetErrors()
        {
            Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
            Sharpen.Tests.IsFalse(metadata.HasErrors());
            ExifSubIFDDirectory directory = metadata.GetOrCreateDirectory <ExifSubIFDDirectory>();

            directory.AddError("Test Error 1");
            Sharpen.Tests.IsTrue(metadata.HasErrors());
        }
 public static IptcDirectory ProcessBytes([NotNull] string filePath)
 {
     Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
     sbyte[] bytes = FileUtil.ReadBytes(filePath);
     new IptcReader().Extract(new SequentialByteArrayReader(bytes), metadata, bytes.Length);
     IptcDirectory directory = metadata.GetFirstDirectoryOfType<IptcDirectory>();
     NUnit.Framework.Assert.IsNotNull(directory);
     return directory;
 }
        public static IptcDirectory ProcessBytes(string filePath)
        {
            Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
            sbyte[] bytes = FileUtil.ReadBytes(filePath);
            new IptcReader().Extract(new SequentialByteArrayReader(bytes), metadata, bytes.Length);
            IptcDirectory directory = metadata.GetDirectory <IptcDirectory>();

            NUnit.Framework.Assert.IsNotNull(directory);
            return(directory);
        }
示例#10
0
        public virtual void Extract([NotNull] RandomAccessReader reader, [NotNull] Com.Drew.Metadata.Metadata metadata)
        {
            // TODO review whether the 'tagPtr' values below really do require RandomAccessReader or whether SequentialReader may be used instead
            IccDirectory directory = new IccDirectory();

            try
            {
                int profileByteCount = reader.GetInt32(IccDirectory.TagProfileByteCount);
                directory.SetInt(IccDirectory.TagProfileByteCount, profileByteCount);
                // For these tags, the int value of the tag is in fact it's offset within the buffer.
                Set4ByteString(directory, IccDirectory.TagCmmType, reader);
                SetInt32(directory, IccDirectory.TagProfileVersion, reader);
                Set4ByteString(directory, IccDirectory.TagProfileClass, reader);
                Set4ByteString(directory, IccDirectory.TagColorSpace, reader);
                Set4ByteString(directory, IccDirectory.TagProfileConnectionSpace, reader);
                SetDate(directory, IccDirectory.TagProfileDatetime, reader);
                Set4ByteString(directory, IccDirectory.TagSignature, reader);
                Set4ByteString(directory, IccDirectory.TagPlatform, reader);
                SetInt32(directory, IccDirectory.TagCmmFlags, reader);
                Set4ByteString(directory, IccDirectory.TagDeviceMake, reader);
                int temp = reader.GetInt32(IccDirectory.TagDeviceModel);
                if (temp != 0)
                {
                    if (temp <= unchecked ((int)(0x20202020)))
                    {
                        directory.SetInt(IccDirectory.TagDeviceModel, temp);
                    }
                    else
                    {
                        directory.SetString(IccDirectory.TagDeviceModel, GetStringFromInt32(temp));
                    }
                }
                SetInt32(directory, IccDirectory.TagRenderingIntent, reader);
                SetInt64(directory, IccDirectory.TagDeviceAttr, reader);
                float[] xyz = new float[] { reader.GetS15Fixed16(IccDirectory.TagXyzValues), reader.GetS15Fixed16(IccDirectory.TagXyzValues + 4), reader.GetS15Fixed16(IccDirectory.TagXyzValues + 8) };
                directory.SetObject(IccDirectory.TagXyzValues, xyz);
                // Process 'ICC tags'
                int tagCount = reader.GetInt32(IccDirectory.TagTagCount);
                directory.SetInt(IccDirectory.TagTagCount, tagCount);
                for (int i = 0; i < tagCount; i++)
                {
                    int     pos     = IccDirectory.TagTagCount + 4 + i * 12;
                    int     tagType = reader.GetInt32(pos);
                    int     tagPtr  = reader.GetInt32(pos + 4);
                    int     tagLen  = reader.GetInt32(pos + 8);
                    sbyte[] b       = reader.GetBytes(tagPtr, tagLen);
                    directory.SetByteArray(tagType, b);
                }
            }
            catch (IOException ex)
            {
                directory.AddError("Exception reading ICC profile: " + ex.Message);
            }
            metadata.AddDirectory(directory);
        }
示例#11
0
 public virtual void ReadJpegSegments([NotNull] Iterable <sbyte[]> segments, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] JpegSegmentType segmentType)
 {
     foreach (sbyte[] segmentBytes in segments)
     {
         // Skip segments not starting with the required header
         if (segmentBytes.Length >= 4 && Preamble.Equals(Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, Preamble.Length)))
         {
             Extract(new ByteArrayReader(segmentBytes), metadata);
         }
     }
 }
 public override void OnExtracted(FilePath file, Com.Drew.Metadata.Metadata metadata)
 {
     base.OnExtracted(file, metadata);
     try
     {
         WriteOutputFile(file, metadata);
     }
     catch (IOException e)
     {
         Sharpen.Runtime.PrintStackTrace(e);
     }
 }
            /// <exception cref="System.IO.IOException"/>
            private void WriteOutputFile(FilePath file, Com.Drew.Metadata.Metadata metadata)
            {
                FileWriter writer = null;

                try
                {
                    string outputPath = Sharpen.Extensions.StringFormat("%s/metadata/%s.txt", file.GetParent(), file.GetName()).ToLower();
                    writer = new FileWriter(outputPath, false);
                    writer.Write("FILE: " + file.GetName() + "\n");
                    writer.Write("\n");
                    if (metadata.HasErrors())
                    {
                        foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
                        {
                            if (!directory.HasErrors())
                            {
                                continue;
                            }
                            foreach (string error in directory.GetErrors())
                            {
                                writer.Write(Sharpen.Extensions.StringFormat("[ERROR: %s] %s\n", directory.GetName(), error));
                            }
                        }
                        writer.Write("\n");
                    }
                    // Iterate through all values
                    foreach (Com.Drew.Metadata.Directory directory_1 in metadata.GetDirectories())
                    {
                        string directoryName = directory_1.GetName();
                        foreach (Tag tag in directory_1.GetTags())
                        {
                            string tagName     = tag.GetTagName();
                            string description = tag.GetDescription();
                            writer.Write(Sharpen.Extensions.StringFormat("[%s - %s] %s = %s%n", directoryName, tag.GetTagTypeHex(), tagName, description));
                        }
                        if (directory_1.GetTagCount() != 0)
                        {
                            writer.Write("\n");
                        }
                    }
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Write("Generated using metadata-extractor\n");
                        writer.Write("http://drewnoakes.com/code/exif/\n");
                        writer.Flush();
                        writer.Close();
                    }
                }
            }
 public override void OnExtracted(FilePath file, Com.Drew.Metadata.Metadata metadata)
 {
     base.OnExtracted(file, metadata);
     // Iterate through all values, calling toString to flush out any formatting exceptions
     foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
     {
         directory.GetName();
         foreach (Tag tag in directory.GetTags())
         {
             tag.GetTagName();
             tag.GetDescription();
         }
     }
 }
 public virtual void OnExtracted(FilePath file, Com.Drew.Metadata.Metadata metadata)
 {
     if (metadata.HasErrors())
     {
         System.Console.Error.Println(file);
         foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
         {
             if (!directory.HasErrors())
             {
                 continue;
             }
             foreach (string error in directory.GetErrors())
             {
                 System.Console.Error.Printf("\t[%s] %s%n", directory.GetName(), error);
                 _errorCount++;
             }
         }
     }
 }
 public virtual void TestRead()
 {
     sbyte[] jfifData = new sbyte[] { 74, 70, 73, 70, 0, 1, 2, 1, 0, 108, 0, 108, 0, 0 };
     Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
     JfifReader reader = new JfifReader();
     reader.Extract(new ByteArrayReader(jfifData), metadata);
     Sharpen.Tests.AreEqual(1, metadata.GetDirectoryCount());
     JfifDirectory directory = metadata.GetFirstDirectoryOfType<JfifDirectory>();
     NUnit.Framework.Assert.IsNotNull(directory);
     Sharpen.Tests.IsFalse(Sharpen.Extensions.ConvertToString(directory.GetErrors()), directory.HasErrors());
     Tag[] tags = Sharpen.Collections.ToArray(directory.GetTags(), new Tag[directory.GetTagCount()]);
     Sharpen.Tests.AreEqual(4, tags.Length);
     Sharpen.Tests.AreEqual(JfifDirectory.TagVersion, tags[0].GetTagType());
     Sharpen.Tests.AreEqual(unchecked((int)(0x0102)), directory.GetInt(tags[0].GetTagType()));
     Sharpen.Tests.AreEqual(JfifDirectory.TagUnits, tags[1].GetTagType());
     Sharpen.Tests.AreEqual(1, directory.GetInt(tags[1].GetTagType()));
     Sharpen.Tests.AreEqual(JfifDirectory.TagResx, tags[2].GetTagType());
     Sharpen.Tests.AreEqual(108, directory.GetInt(tags[2].GetTagType()));
     Sharpen.Tests.AreEqual(JfifDirectory.TagResy, tags[3].GetTagType());
     Sharpen.Tests.AreEqual(108, directory.GetInt(tags[3].GetTagType()));
 }
                internal Row(MarkdownTableOutputHandler _enclosing, [NotNull] FilePath file, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] string relativePath)
                {
                    this._enclosing   = _enclosing;
                    this.file         = file;
                    this.metadata     = metadata;
                    this.relativePath = relativePath;
                    ExifIFD0Directory      ifd0Dir   = metadata.GetFirstDirectoryOfType <ExifIFD0Directory>();
                    ExifSubIFDDirectory    subIfdDir = metadata.GetFirstDirectoryOfType <ExifSubIFDDirectory>();
                    ExifThumbnailDirectory thumbDir  = metadata.GetFirstDirectoryOfType <ExifThumbnailDirectory>();

                    if (ifd0Dir != null)
                    {
                        this.manufacturer = ifd0Dir.GetDescription(ExifIFD0Directory.TagMake);
                        this.model        = ifd0Dir.GetDescription(ExifIFD0Directory.TagModel);
                    }
                    bool hasMakernoteData = false;

                    if (subIfdDir != null)
                    {
                        this.exifVersion = subIfdDir.GetDescription(ExifSubIFDDirectory.TagExifVersion);
                        hasMakernoteData = subIfdDir.ContainsTag(ExifSubIFDDirectory.TagMakernote);
                    }
                    if (thumbDir != null)
                    {
                        int?width  = thumbDir.GetInteger(ExifThumbnailDirectory.TagImageWidth);
                        int?height = thumbDir.GetInteger(ExifThumbnailDirectory.TagImageHeight);
                        this.thumbnail = width != null && height != null?Sharpen.Extensions.StringFormat("Yes (%s x %s)", width, height) : "Yes";
                    }
                    foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
                    {
                        if (directory.GetType().FullName.Contains("Makernote"))
                        {
                            this.makernote = Sharpen.Extensions.Trim(directory.GetName().Replace("Makernote", string.Empty));
                        }
                    }
                    if (this.makernote == null)
                    {
                        this.makernote = hasMakernoteData ? "(Unknown)" : "N/A";
                    }
                }
示例#18
0
        /// <summary>
        /// Performs the Jfif data extraction, adding found values to the specified
        /// instance of
        /// <see cref="Com.Drew.Metadata.Metadata"/>
        /// .
        /// </summary>
        public virtual void Extract([NotNull] RandomAccessReader reader, [NotNull] Com.Drew.Metadata.Metadata metadata)
        {
            JfifDirectory directory = new JfifDirectory();

            metadata.AddDirectory(directory);
            try
            {
                // For JFIF, the tag number is also the offset into the segment
                int ver = reader.GetUInt16(JfifDirectory.TagVersion);
                directory.SetInt(JfifDirectory.TagVersion, ver);
                int units = reader.GetUInt8(JfifDirectory.TagUnits);
                directory.SetInt(JfifDirectory.TagUnits, units);
                int height = reader.GetUInt16(JfifDirectory.TagResx);
                directory.SetInt(JfifDirectory.TagResx, height);
                int width = reader.GetUInt16(JfifDirectory.TagResy);
                directory.SetInt(JfifDirectory.TagResy, width);
            }
            catch (IOException me)
            {
                directory.AddError(me.Message);
            }
        }
        public virtual void TestRead()
        {
            sbyte[] jfifData = new sbyte[] { 74, 70, 73, 70, 0, 1, 2, 1, 0, 108, 0, 108, 0, 0 };
            Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata();
            JfifReader reader = new JfifReader();

            reader.Extract(new ByteArrayReader(jfifData), metadata);
            Sharpen.Tests.AreEqual(1, metadata.GetDirectoryCount());
            JfifDirectory directory = metadata.GetFirstDirectoryOfType <JfifDirectory>();

            NUnit.Framework.Assert.IsNotNull(directory);
            Sharpen.Tests.IsFalse(Sharpen.Extensions.ConvertToString(directory.GetErrors()), directory.HasErrors());
            Tag[] tags = Sharpen.Collections.ToArray(directory.GetTags(), new Tag[directory.GetTagCount()]);
            Sharpen.Tests.AreEqual(4, tags.Length);
            Sharpen.Tests.AreEqual(JfifDirectory.TagVersion, tags[0].GetTagType());
            Sharpen.Tests.AreEqual(unchecked ((int)(0x0102)), directory.GetInt(tags[0].GetTagType()));
            Sharpen.Tests.AreEqual(JfifDirectory.TagUnits, tags[1].GetTagType());
            Sharpen.Tests.AreEqual(1, directory.GetInt(tags[1].GetTagType()));
            Sharpen.Tests.AreEqual(JfifDirectory.TagResx, tags[2].GetTagType());
            Sharpen.Tests.AreEqual(108, directory.GetInt(tags[2].GetTagType()));
            Sharpen.Tests.AreEqual(JfifDirectory.TagResy, tags[3].GetTagType());
            Sharpen.Tests.AreEqual(108, directory.GetInt(tags[3].GetTagType()));
        }
示例#20
0
        public virtual void Extract(RandomAccessReader reader, Com.Drew.Metadata.Metadata metadata)
        {
            PsdHeaderDirectory directory = metadata.GetOrCreateDirectory <PsdHeaderDirectory>();

            try
            {
                int signature = reader.GetInt32(0);
                if (signature != unchecked ((int)(0x38425053)))
                {
                    directory.AddError("Invalid PSD file signature");
                    return;
                }
                int version = reader.GetUInt16(4);
                if (version != 1 && version != 2)
                {
                    directory.AddError("Invalid PSD file version (must be 1 or 2)");
                    return;
                }
                // 6 reserved bytes are skipped here.  They should be zero.
                int channelCount = reader.GetUInt16(12);
                directory.SetInt(PsdHeaderDirectory.TagChannelCount, channelCount);
                // even though this is probably an unsigned int, the max height in practice is 300,000
                int imageHeight = reader.GetInt32(14);
                directory.SetInt(PsdHeaderDirectory.TagImageHeight, imageHeight);
                // even though this is probably an unsigned int, the max width in practice is 300,000
                int imageWidth = reader.GetInt32(18);
                directory.SetInt(PsdHeaderDirectory.TagImageWidth, imageWidth);
                int bitsPerChannel = reader.GetUInt16(22);
                directory.SetInt(PsdHeaderDirectory.TagBitsPerChannel, bitsPerChannel);
                int colorMode = reader.GetUInt16(24);
                directory.SetInt(PsdHeaderDirectory.TagColorMode, colorMode);
            }
            catch (IOException)
            {
                directory.AddError("Unable to read PSD header");
            }
        }
            public override void OnExtracted(FilePath file, Com.Drew.Metadata.Metadata metadata)
            {
                base.OnExtracted(file, metadata);
                string extension = GetExtension(file);

                if (extension == null)
                {
                    return;
                }
                // Sanitise the extension
                extension = extension.ToLower();
                if (_extensionEquivalence.ContainsKey(extension))
                {
                    extension = _extensionEquivalence.Get(extension);
                }
                IList <ProcessAllImagesInFolderUtility.WikiTableOutputHandler.Row> list = _rowListByExtension.Get(extension);

                if (list == null)
                {
                    list = new AList <ProcessAllImagesInFolderUtility.WikiTableOutputHandler.Row>();
                    _rowListByExtension.Put(extension, list);
                }
                list.Add(new ProcessAllImagesInFolderUtility.WikiTableOutputHandler.Row(this, file, metadata));
            }
        /// <summary>An application entry point.</summary>
        /// <remarks>
        /// An application entry point.  Takes the name of one or more files as arguments and prints the contents of all
        /// metadata directories to <code>System.out</code>.
        /// <p/>
        /// If <code>-thumb</code> is passed, then any thumbnail data will be written to a file with name of the
        /// input file having <code>.thumb.jpg</code> appended.
        /// <p/>
        /// If <code>-wiki</code> is passed, then output will be in a format suitable for Google Code's wiki.
        /// <p/>
        /// If <code>-hex</code> is passed, then the ID of each tag will be displayed in hexadecimal.
        /// </remarks>
        /// <param name="args">the command line arguments</param>
        /// <exception cref="Com.Drew.Metadata.MetadataException"/>
        /// <exception cref="System.IO.IOException"/>
        public static void Main(string[] args)
        {
            ICollection <string> argList = new AList <string>(Arrays.AsList(args));
            bool thumbRequested          = argList.Remove("-thumb");
            bool wikiFormat = argList.Remove("-wiki");
            bool showHex    = argList.Remove("-hex");

            if (argList.Count < 1)
            {
                string version = typeof(Com.Drew.Imaging.ImageMetadataReader).Assembly.GetImplementationVersion();
                System.Console.Out.Println("metadata-extractor version " + version);
                System.Console.Out.Println();
                System.Console.Out.Println(Sharpen.Extensions.StringFormat("Usage: java -jar metadata-extractor-%s.jar <filename> [<filename>] [-thumb] [-wiki] [-hex]", version == null ? "a.b.c" : version));
                System.Environment.Exit(1);
            }
            foreach (string filePath in argList)
            {
                long     startTime = Runtime.NanoTime();
                FilePath file      = new FilePath(filePath);
                if (!wikiFormat && argList.Count > 1)
                {
                    System.Console.Out.Printf("\n***** PROCESSING: %s\n%n", filePath);
                }
                Com.Drew.Metadata.Metadata metadata = null;
                try
                {
                    metadata = Com.Drew.Imaging.ImageMetadataReader.ReadMetadata(file);
                }
                catch (Exception e)
                {
                    Sharpen.Runtime.PrintStackTrace(e, System.Console.Error);
                    System.Environment.Exit(1);
                }
                long took = Runtime.NanoTime() - startTime;
                if (!wikiFormat)
                {
                    System.Console.Out.Printf("Processed %.3f MB file in %.2f ms%n%n", file.Length() / (1024d * 1024), took / 1000000d);
                }
                if (wikiFormat)
                {
                    string            fileName          = file.GetName();
                    string            urlName           = StringUtil.UrlEncode(fileName);
                    ExifIFD0Directory exifIFD0Directory = metadata.GetDirectory <ExifIFD0Directory>();
                    string            make  = exifIFD0Directory == null ? string.Empty : StringUtil.EscapeForWiki(exifIFD0Directory.GetString(ExifIFD0Directory.TagMake));
                    string            model = exifIFD0Directory == null ? string.Empty : StringUtil.EscapeForWiki(exifIFD0Directory.GetString(ExifIFD0Directory.TagModel));
                    System.Console.Out.Println();
                    System.Console.Out.Println("-----");
                    System.Console.Out.Println();
                    System.Console.Out.Printf("= %s - %s =%n", make, model);
                    System.Console.Out.Println();
                    System.Console.Out.Printf("<a href=\"http://sample-images.metadata-extractor.googlecode.com/git/%s\">%n", urlName);
                    System.Console.Out.Printf("<img src=\"http://sample-images.metadata-extractor.googlecode.com/git/%s\" width=\"300\"/><br/>%n", urlName);
                    System.Console.Out.Println(StringUtil.EscapeForWiki(fileName));
                    System.Console.Out.Println("</a>");
                    System.Console.Out.Println();
                    System.Console.Out.Println("|| *Directory* || *Tag Id* || *Tag Name* || *Extracted Value* ||");
                }
                // iterate over the metadata and print to System.out
                foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories())
                {
                    string directoryName = directory.GetName();
                    foreach (Tag tag in directory.GetTags())
                    {
                        string tagName     = tag.GetTagName();
                        string description = tag.GetDescription();
                        // truncate the description if it's too long
                        if (description != null && description.Length > 1024)
                        {
                            description = Sharpen.Runtime.Substring(description, 0, 1024) + "...";
                        }
                        if (wikiFormat)
                        {
                            System.Console.Out.Printf("||%s||0x%s||%s||%s||%n", StringUtil.EscapeForWiki(directoryName), Sharpen.Extensions.ToHexString(tag.GetTagType()), StringUtil.EscapeForWiki(tagName), StringUtil.EscapeForWiki(description));
                        }
                        else
                        {
                            if (showHex)
                            {
                                System.Console.Out.Printf("[%s - %s] %s = %s%n", directoryName, tag.GetTagTypeHex(), tagName, description);
                            }
                            else
                            {
                                System.Console.Out.Printf("[%s] %s = %s%n", directoryName, tagName, description);
                            }
                        }
                    }
                    // print out any errors
                    foreach (string error in directory.GetErrors())
                    {
                        System.Console.Error.Println("ERROR: " + error);
                    }
                }
                if (args.Length > 1 && thumbRequested)
                {
                    ExifThumbnailDirectory directory_1 = metadata.GetDirectory <ExifThumbnailDirectory>();
                    if (directory_1 != null && directory_1.HasThumbnailData())
                    {
                        System.Console.Out.Println("Writing thumbnail...");
                        directory_1.WriteThumbnail(Sharpen.Extensions.Trim(args[0]) + ".thumb.jpg");
                    }
                    else
                    {
                        System.Console.Out.Println("No thumbnail data exists in this image");
                    }
                }
            }
        }