Ejemplo n.º 1
0
        /// <summary>
        /// Will stock the thumbnail into exif directory if available.
        /// </summary>
        /// <param name="exifDirectory">where to stock the thumbnail</param>
        /// <param name="tiffHeaderOffset">the tiff lcHeader lcOffset value</param>
        private void StoreThumbnailBytes(AbstractDirectory exifDirectory, int tiffHeaderOffset)
        {
            if (!exifDirectory.ContainsTag(ExifDirectory.TAG_COMPRESSION))
            {
                return;
            }

            if (!exifDirectory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_LENGTH) ||
                !exifDirectory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_OFFSET))
            {
                return;
            }
            try
            {
                int    offset = exifDirectory.GetInt(ExifDirectory.TAG_THUMBNAIL_OFFSET);
                int    length = exifDirectory.GetInt(ExifDirectory.TAG_THUMBNAIL_LENGTH);
                byte[] result = new byte[length];
                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = base.data[tiffHeaderOffset + offset + i];
                }
                exifDirectory.SetObject(ExifDirectory.TAG_THUMBNAIL_DATA, result);
            }
            catch (Exception e)
            {
                exifDirectory.HasError = true;
                Trace.TraceError("Unable to extract thumbnail: " + e.Message);
            }
        }
Ejemplo n.º 2
0
        public override void visit(AbstractDirectory dir)
        {
            //++depth;
            var nextDir = dir as Directory.Directory;

            if (nextDir != null)
            {
                ++depth;
                Retreat(depth);
                Console.WriteLine(nextDir.Name);
                Retreat(depth);
                Console.WriteLine("{");
                //++depth;
                Retreat(depth);
                foreach (var abstractDirectory in nextDir.ChildrenList)
                {
                    abstractDirectory.accept(this);
                }
                --depth;
                Console.WriteLine("}");
            }
            else
            {
                Retreat(depth + 1);
                Console.WriteLine(dir);
            }
            Retreat(depth);
        }
Ejemplo n.º 3
0
		public File(FileData file, AbstractDirectory parent)
		{
			Parent = parent;

			NewName = file.Name;
			Name = file.Name;
			Title = file.Name;
			Size = file.Length;
			Updated = file.Updated;
			Created = file.Created;
		}
 /// <summary>
 /// Creates a directory tag.
 /// </summary>
 /// <param name="aBuff">where to put info</param>
 /// <param name="aDirectory">the information to add</param>
 protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory)
 {
     if (aDirectory != null)
     {
         aBuff.Append("--| ").Append(aDirectory.GetName()).Append(" |--");
         aBuff.AppendLine();
         foreach (Tag lcTag in aDirectory)
         {
             CreateTag(aBuff, lcTag);
         }
     }
 }
 /// <summary>
 /// Creates a directory tag.
 ///
 /// Examples :
 /// <pre>
 /// &lt;directory name="Exif"&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 /// &lt;/directory&gt;
 /// </pre>
 /// </summary>
 /// <param name="aBuff">where to put info</param>
 /// <param name="aDirectory">the information to add</param>
 protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory)
 {
     if (aDirectory != null)
     {
         this.Open(aBuff, "directory", "name", aDirectory.GetName(), "class", aDirectory.GetType(), true);
         foreach (Tag lcTag in aDirectory)
         {
             this.CreateTag(aBuff, lcTag);
         }
         this.Close(aBuff, "directory", true);
     }
 }
 /// <summary>
 /// Creates a directory tag.
 ///
 /// Examples :
 /// <pre>
 /// &lt;directory name="Exif"&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 /// &lt;/directory&gt;
 /// </pre>
 /// </summary>
 /// <param name="aBuff">where to put info</param>
 /// <param name="aDirectory">the information to add</param>
 protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory)
 {
     if (aDirectory != null)
     {
         Open(aBuff, "directory name=\"" + aDirectory.GetName() + "\"", true);
         foreach (Tag lcTag in aDirectory)
         {
             CreateTag(aBuff, lcTag);
         }
         Close(aBuff, "directory", true);
     }
 }
 /// <summary>
 /// Creates a directory tag.
 ///
 /// Examples :
 /// <pre>
 /// &lt;directory name="Exif"&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 /// &lt;/directory&gt;
 /// </pre>
 /// </summary>
 /// <param name="aBuff">where to put info</param>
 /// <param name="aDirectory">the information to add</param>
 protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory)
 {
     if (aDirectory != null)
     {
         this.Open(aBuff, "directory", "name", aDirectory.GetName(), "class", aDirectory.GetType(), true);
         IEnumerator <Tag> lcTagsEnum = aDirectory.GetTagIterator();
         while (lcTagsEnum.MoveNext())
         {
             this.CreateTag(aBuff, lcTagsEnum.Current);
         }
         this.Close(aBuff, "directory", true);
     }
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Transform the metatdat object into an XML stream.
        /// </summary>
        /// <returns>The metadata object as XML stream</returns>
        public virtual string AsText()
        {
            StringBuilder lcBuff = new StringBuilder();
            IEnumerator <AbstractDirectory> lcDirectoryEnum = this.Metadata.GetDirectoryIterator();

            while (lcDirectoryEnum.MoveNext())
            {
                AbstractDirectory lcDirectory = lcDirectoryEnum.Current;
                CreateDirectory(lcBuff, lcDirectory);
                lcDirectory = null;
            }
            return(lcBuff.ToString());
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Extracts aMetadata
        /// </summary>
        /// <param name="aMetadata">where to add aMetadata</param>
        /// <returns>the aMetadata found</returns>
        public override Metadata Extract(Metadata aMetadata)
        {
            if (base.data == null)
            {
                return(aMetadata);
            }

            AbstractDirectory lcDirectory = aMetadata.GetDirectory("com.drew.metadata.jpeg.JpegCommentDirectory");
            string            comment     = Utils.Decode(base.data, true);

            lcDirectory.SetObject(JpegCommentDirectory.TAG_JPEG_COMMENT, comment);
            return(aMetadata);
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Creates a directory tag.
 ///
 /// Examples :
 /// <pre>
 /// &lt;directory name="Exif"&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 ///   &lt;tag&gt;
 ///     ...
 ///   &lt;/tag&gt;
 /// &lt;/directory&gt;
 /// </pre>
 /// </summary>
 /// <param name="aBuff">where to put info</param>
 /// <param name="aDirectory">the information to add</param>
 protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory)
 {
     if (aDirectory != null)
     {
         Open(aBuff, "directory name=\"" + aDirectory.GetName() + "\"", true);
         IEnumerator <Tag> lcTagsEnum = aDirectory.GetTagIterator();
         while (lcTagsEnum.MoveNext())
         {
             Tag lcTag = lcTagsEnum.Current;
             CreateTag(aBuff, lcTag);
             lcTag = null;
         }
         Close(aBuff, "directory", true);
     }
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Creates a directory tag.
 /// </summary>
 /// <param name="aBuff">where to put info</param>
 /// <param name="aDirectory">the information to add</param>
 protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory)
 {
     if (aDirectory != null)
     {
         aBuff.Append("--| ").Append(aDirectory.GetName()).Append(" |--");
         aBuff.AppendLine();
         IEnumerator <Tag> lcTagsEnum = aDirectory.GetTagIterator();
         while (lcTagsEnum.MoveNext())
         {
             Tag lcTag = lcTagsEnum.Current;
             CreateTag(aBuff, lcTag);
             lcTag = null;
         }
     }
 }
Ejemplo n.º 12
0
        public File(IFileSystem fs, FileData file, AbstractDirectory parent)
            : base(fs)
        {
            Parent = parent;

            NewName = file.Name;
            Name = file.Name;
            Title = file.Name;
            Size = file.Length;
            Updated = file.Updated;
            Created = file.Created;

            url = file.VirtualPath;

            string icon = ImagesUtility.GetResizedPath(file.VirtualPath, "icon");
            if (FileSystem.FileExists(icon))
                this.iconUrl = icon;
        }
Ejemplo n.º 13
0
        private void SyncDirectory(AbstractDirectory source, AbstractDirectory destination)
        {
            if (destination.Exists)
            {
                var directoriesInSource      = source.GetDirectories().GetEnumerator();
                var directoriesInDestination = destination.GetDirectories().GetEnumerator();

                Sync(directoriesInSource, directoriesInDestination, destination, SyncDirectory);

                var regularFilesInSource      = source.GetRegularFiles().GetEnumerator();
                var regularFilesInDestination = destination.GetRegularFiles().GetEnumerator();

                Sync(regularFilesInSource, regularFilesInDestination, destination, SyncRegularFile);
                destination.SetAllAttributes(source);
            }
            else
            {
                source.Copy(destination);
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="aDirectory">a base.directory</param>
 public IptcDescriptor(AbstractDirectory aDirectory) : base(aDirectory)
 {
 }
Ejemplo n.º 15
0
        private void WriteSearch(HttpContext context)
        {
            var query = context.Request["query"];

            if (string.IsNullOrWhiteSpace(query))
            {
                context.Response.WriteJson(new { Status = "Error", Total = 0, Message = "Please provide a search term." });
                return;
            }
            query = query.TrimStart().TrimEnd();

            var host     = Engine.Resolve <IHost>();
            var rootItem = Engine.Persister.Get(host.DefaultSite.RootItemID);
            var root     = new HierarchyNode <ContentItem>(rootItem);

            FS = Engine.Resolve <IFileSystem>();
            var selectionTrail    = Find.EnumerateParents(Selection.SelectedItem, null, true).ToList().Where(a => a is AbstractNode).Reverse().ToList();
            var uploadDirectories = MediaBrowserUtils.GetAvailableUploadFoldersForAllSites(context, root, selectionTrail, Engine, FS);

            if (uploadDirectories.Count == 0)
            {
                context.Response.WriteJson(new { Status = "Error", Total = 0, Message = "No available directories in this site." });
                return;
            }

            //Do the search using the IFileSystem
            var resultsFileData = FS.SearchFiles(query, uploadDirectories);

            if (!resultsFileData.Any())
            {
                context.Response.WriteJson(new { Status = "Error", Total = 0, Message = "0 files found." });
                return;
            }

            var files                = new List <File>();
            var fileMap              = new Dictionary <string, File>(StringComparer.OrdinalIgnoreCase);
            var lastParent           = string.Empty;
            AbstractDirectory parent = null;

            foreach (var fd in resultsFileData.OrderBy(s => s.VirtualPath))
            {
                var parentDirectory = fd.VirtualPath.Substring(0, fd.VirtualPath.LastIndexOf('/'));
                if (lastParent != parentDirectory)
                {
                    parent     = new Directory(DirectoryData.Virtual(parentDirectory), null);
                    lastParent = parentDirectory;
                }

                var file = new File(fd, parent);
                file.Set(FS);
                file.Set(ImageSizes);

                var unresizedFileName = ImageSizes.RemoveImageSize(file.Name);
                if (unresizedFileName != null && fileMap.ContainsKey(unresizedFileName))
                {
                    fileMap[unresizedFileName].Add(file);

                    if (ImageSizes.GetSizeName(file.Name) == "icon")
                    {
                        file.IsIcon = true;
                    }
                }
                else
                {
                    if (unresizedFileName == null)
                    {
                        files.Add(file);
                        fileMap[file.Name] = file;
                    }
                }
            }
            files.Sort(new TitleComparer <File>());

            var directory  = FS.GetDirectory("/");
            var fsRootPath = directory != null && !string.IsNullOrWhiteSpace(directory.RootPath) ? directory.RootPath : "";

            var selectableExtensions = context.Request["exts"];

            context.Response.WriteJson(new
            {
                Path  = "",
                Total = files.Count,
                Files = GetFileReducedList(files, ImageSizes, selectableExtensions, fsRootPath)
            });
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Extracts aMetadata
        /// </summary>
        /// <param name="aMetadata">where to add aMetadata</param>
        /// <returns>the aMetadata found</returns>
        public override Metadata Extract(Metadata aMetadata)
        {
            if (base.data == null)
            {
                return(aMetadata);
            }

            AbstractDirectory lcDirectory = aMetadata.GetDirectory("com.drew.metadata.iptc.IptcDirectory");

            // find start of data
            int offset = 0;

            try
            {
                while (offset < base.data.Length - 1 && Get32Bits(offset) != 0x1c02)
                {
                    offset++;
                }
            }
            catch (MetadataException e)
            {
                lcDirectory.HasError = true;
                Trace.TraceError(
                    "Couldn't find start of Iptc data (invalid segment) (" + e.Message + ")");
                return(aMetadata);
            }

            // for each tag
            while (offset < base.data.Length)
            {
                // identifies start of a tag
                if (base.data[offset] != 0x1c)
                {
                    break;
                }
                // we need at least five bytes left to read a tag
                if ((offset + 5) >= base.data.Length)
                {
                    break;
                }

                offset++;

                int directoryType;
                int tagType;
                int tagByteCount;
                try
                {
                    directoryType = base.data[offset++];
                    tagType       = base.data[offset++];
                    tagByteCount  = Get32Bits(offset);
                }
                catch (MetadataException e)
                {
                    lcDirectory.HasError = true;
                    Trace.TraceError(
                        "Iptc data segment ended mid-way through tag descriptor (" + e.Message + ")");
                    return(aMetadata);
                }
                offset += 2;
                if ((offset + tagByteCount) > base.data.Length)
                {
                    lcDirectory.HasError = true;
                    Trace.TraceError(
                        "Data for tag extends beyond end of IPTC segment");
                    break;
                }

                ProcessTag(lcDirectory, directoryType, tagType, offset, tagByteCount);
                offset += tagByteCount;
            }

            return(aMetadata);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Process one of the nested Tiff IFD directories.
        /// 2 bytes: number of tags for each tag
        ///		2 bytes: tag type
        ///		2 bytes: format code
        ///     4 bytes: component count
        /// </summary>
        /// <param name="directory">the directory</param>
        /// <param name="dirStartOffSet">where to start</param>
        private void ProcessDirectory(AbstractDirectory directory, IDictionary <int, string> processedDirectoryOffsets, int dirStartOffset, int tiffHeaderOffset)
        {
            // check for directories we've already visited to avoid stack overflows when recursive/cyclic directory structures exist
            if (processedDirectoryOffsets.ContainsKey(dirStartOffset))
            {
                return;
            }
            // remember that we've visited this directory so that we don't visit it again later
            processedDirectoryOffsets.Add(dirStartOffset, MARK_AS_PROCESSED);

            if (dirStartOffset >= base.data.Length || dirStartOffset < 0)
            {
                directory.HasError = true;
                Trace.TraceError("Ignored directory marked to start outside data segement");
                return;
            }

            if (!IsDirectoryLengthValid(dirStartOffset, tiffHeaderOffset))
            {
                directory.HasError = true;
                Trace.TraceError("Illegally sized directory");
                return;
            }

            // First two bytes in the IFD are the tag count
            int dirTagCount = Get16Bits(dirStartOffset);

            // Handle each tag in this directory
            for (int tagNumber = 0; tagNumber < dirTagCount; tagNumber++)
            {
                int tagOffset = CalculateTagOffset(dirStartOffset, tagNumber);

                // 2 bytes for the tag type
                int tagType = Get16Bits(tagOffset);

                // 2 bytes for the format code
                int formatCode = Get16Bits(tagOffset + 2);
                if (formatCode < 1 || formatCode > MAX_FORMAT_CODE)
                {
                    directory.HasError = true;
                    Trace.TraceError("Invalid format code: " + formatCode);
                    continue;
                }

                // 4 bytes dictate the number of components in this tag'lcStr data
                int componentCount = Get32Bits(tagOffset + 4);
                if (componentCount < 0)
                {
                    directory.HasError = true;
                    Trace.TraceError("Negative component count in EXIF");
                    continue;
                }

                // each component may have more than one byte... calculate the total number of bytes
                int byteCount      = componentCount * BYTES_PER_FORMAT[formatCode];
                int tagValueOffset = CalculateTagValueOffset(byteCount, tagOffset, tiffHeaderOffset);
                if (tagValueOffset < 0 || tagValueOffset > base.data.Length)
                {
                    directory.HasError = true;
                    Trace.TraceError("Illegal pointer offset value in EXIF");
                    continue;
                }


                // Check that this tag isn't going to allocate outside the bounds of the data array.
                // This addresses an uncommon OutOfMemoryError.
                if (byteCount < 0 || tagValueOffset + byteCount > base.data.Length)
                {
                    directory.HasError = true;
                    Trace.TraceError("Illegal number of bytes: " + byteCount);
                    continue;
                }

                // Calculate the value as an lcOffset for cases where the tag represents directory
                int subdirOffset = tiffHeaderOffset + Get32Bits(tagValueOffset);

                switch (tagType)
                {
                case TAG_EXIF_OFFSET:
                    ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
                    continue;

                case TAG_INTEROP_OFFSET:
                    ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.ExifInteropDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
                    continue;

                case TAG_GPS_INFO_OFFSET:
                    ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.GpsDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
                    continue;

                case TAG_MAKER_NOTE:
                    ProcessMakerNote(tagValueOffset, processedDirectoryOffsets, tiffHeaderOffset);
                    continue;

                default:
                    ProcessTag(directory, tagType, tagValueOffset, componentCount, formatCode);
                    break;
                }
            } // End of for
            // at the end of each IFD is an optional link to the next IFD
            int finalTagOffset      = CalculateTagOffset(dirStartOffset, dirTagCount);
            int nextDirectoryOffset = Get32Bits(finalTagOffset);

            if (nextDirectoryOffset != 0)
            {
                nextDirectoryOffset += tiffHeaderOffset;
                if (nextDirectoryOffset >= base.data.Length)
                {
                    Trace.TraceWarning("Last 4 bytes of IFD reference another IFD with an address that is out of bounds\nNote this could have been caused by jhead 1.3 cropping too much");
                    return;
                }
                else if (nextDirectoryOffset < dirStartOffset)
                {
                    Trace.TraceWarning("Last 4 bytes of IFD reference another IFD with an address that is before the start of this directory");
                    return;
                }
                // the next directory is of same type as this one
                ProcessDirectory(directory, processedDirectoryOffsets, nextDirectoryOffset, tiffHeaderOffset);
            }
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="base.directory">a base.directory</param>
 public ExifInteropDescriptor(AbstractDirectory aDirectory) : base(aDirectory)
 {
 }
Ejemplo n.º 19
0
        /// <summary>
        /// This method serves as marsheller of objects for dataset.
        /// It converts from IPTC octets to relevant java object.
        /// </summary>
        /// <param name="aDirectory">the directory</param>
        /// <param name="aDirectoryType">the directory type</param>
        /// <param name="aTagType">the tag type</param>
        /// <param name="anOffset">the lcOffset</param>
        /// <param name="aTagByteCount">the tag byte count</param>
        private void ProcessTag(
            AbstractDirectory aDirectory,
            int aDirectoryType,
            int aTagType,
            int anOffset,
            int aTagByteCount)
        {
            int tagIdentifier = aTagType | (aDirectoryType << 8);

            switch (tagIdentifier)
            {
            case IptcDirectory.TAG_RECORD_VERSION:
                // short
                short shortValue = (short)((base.data[anOffset] << 8) | base.data[anOffset + 1]);
                aDirectory.SetObject(tagIdentifier, shortValue);
                return;

            case IptcDirectory.TAG_URGENCY:
                // byte
                aDirectory.SetObject(tagIdentifier, base.data[anOffset]);
                return;

            case IptcDirectory.TAG_RELEASE_DATE:
            case IptcDirectory.TAG_DATE_CREATED:
                // Date object
                if (aTagByteCount >= 8)
                {
                    string dateStr = Utils.Decode(base.data, anOffset, aTagByteCount, false);
                    try
                    {
                        int      year  = Convert.ToInt32(dateStr.Remove(4));
                        int      month = Convert.ToInt32(dateStr.Substring(4, 2)); //No -1 here;
                        int      day   = Convert.ToInt32(dateStr.Substring(6, 2));
                        DateTime date  = new DateTime(year, month, day);
                        aDirectory.SetObject(tagIdentifier, date);
                        return;
                    }
                    catch (FormatException)
                    {
                        // fall through and we'll store whatever was there as a String
                    }
                }
                break;     // Added for .Net compiler
                //case IptcDirectory.TAG_RELEASE_TIME:
                //case IptcDirectory.TAG_TIME_CREATED:
            }
            // If no special handling by now, treat it as a string
            string str = null;

            if (aTagByteCount < 1)
            {
                str = "";
            }
            else
            {
                str = Utils.Decode(base.data, anOffset, aTagByteCount, false);
            }
            if (aDirectory.ContainsTag(tagIdentifier))
            {
                string[] oldStrings;
                string[] newStrings;
                try
                {
                    oldStrings = aDirectory.GetStringArray(tagIdentifier);
                }
                catch (MetadataException)
                {
                    oldStrings = null;
                }
                if (oldStrings == null)
                {
                    newStrings = new String[1];
                }
                else
                {
                    newStrings = new string[oldStrings.Length + 1];
                    for (int i = 0; i < oldStrings.Length; i++)
                    {
                        newStrings[i] = oldStrings[i];
                    }
                }
                newStrings[newStrings.Length - 1] = str;
                aDirectory.SetObject(tagIdentifier, newStrings);
            }
            else
            {
                aDirectory.SetObject(tagIdentifier, str);
            }
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="directory">a directory</param>
 public JpegCommentDescriptor(AbstractDirectory directory) : base(directory)
 {
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Performs the Exif data extraction, adding found values to the specified instance of Metadata.
        /// </summary>
        /// <param name="aMetadata">where to add meta data</param>
        /// <returns>the aMetadata</returns>
        public override Metadata Extract(Metadata metadata)
        {
            this.metadata = metadata;
            if (base.data == null)
            {
                return(this.metadata);
            }

            // once we know there'str some data, create the directory and start working on it
            AbstractDirectory directory = this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory");

            if (base.data.Length <= 14)
            {
                directory.HasError = true;
                Trace.TraceError("Exif data segment must contain at least 14 bytes");
                return(this.metadata);
            }
            if (!"Exif\0\0".Equals(Utils.Decode(base.data, 0, 6, false)))
            {
                directory.HasError = true;
                Trace.TraceError("Exif data segment doesn't begin with 'Exif'");
                return(this.metadata);
            }

            // this should be either "MM" or "II"
            string byteOrderIdentifier = Utils.Decode(base.data, 6, 2, false);

            if (!SetByteOrder(byteOrderIdentifier))
            {
                directory.HasError = true;
                Trace.TraceError("Unclear distinction between Motorola/Intel byte ordering");
                return(this.metadata);
            }

            // Check the next two values for correctness.
            if (Get16Bits(8) != 0x2a)
            {
                directory.HasError = true;
                Trace.TraceError("Invalid Exif start - should have 0x2A at offSet 8 in Exif header");
                return(this.metadata);
            }

            int firstDirectoryOffSet = Get32Bits(10) + TIFF_HEADER_START_OFFSET;

            // David Ekholm sent an digital camera image that has this problem
            if (firstDirectoryOffSet >= base.data.Length - 1)
            {
                directory.HasError = true;
                Trace.TraceError("First exif directory offSet is beyond end of Exif data segment");
                // First directory normally starts 14 bytes in -- try it here and catch another error in the worst case
                firstDirectoryOffSet = 14;
            }

            // 0th IFD (we merge with Exif IFD)
            //ProcessDirectory(directory, firstDirectoryOffSet);
            // after the extraction process, if we have the correct tags, we may be able to extract thumbnail information
            //ExtractThumbnail(directory);

            Dictionary <int, string> processedDirectoryOffsets = new Dictionary <int, string>();

            // 0th IFD (we merge with Exif IFD)
            ProcessDirectory(directory, processedDirectoryOffsets, firstDirectoryOffSet, TIFF_HEADER_START_OFFSET);

            // after the extraction process, if we have the correct tags, we may be able to store thumbnail information
            StoreThumbnailBytes(directory, TIFF_HEADER_START_OFFSET);


            return(this.metadata);
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="aDirectory">a base.directory</param>
 public CasioType1Descriptor(AbstractDirectory aDirectory) : base(aDirectory)
 {
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Determine the camera model and makernote format
        /// </summary>
        /// <param name="subdirOffset">the sub lcOffset dir</param>
        /// <param name="processedDirectoryOffsets">the processed directory offsets</param>
        /// <param name="tiffHeaderOffset">the tiff lcHeader lcOffset</param>
        private void ProcessMakerNote(int subdirOffset, IDictionary <int, string> processedDirectoryOffsets, int tiffHeaderOffset)
        {
            // Console.WriteLine("ProcessMakerNote value="+subdirOffSet);
            // Determine the camera model and makernote format
            AbstractDirectory exifDirectory = this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory");

            if (exifDirectory == null)
            {
                return;
            }

            string cameraModel     = exifDirectory.GetString(ExifDirectory.TAG_MAKE);
            string firstTwoChars   = Utils.Decode(base.data, subdirOffset, 2, false);
            string firstThreeChars = Utils.Decode(base.data, subdirOffset, 3, false);
            string firstFourChars  = Utils.Decode(base.data, subdirOffset, 4, false);
            string firstFiveChars  = Utils.Decode(base.data, subdirOffset, 5, false);
            string firstSixChars   = Utils.Decode(base.data, subdirOffset, 6, false);
            string firstSevenChars = Utils.Decode(base.data, subdirOffset, 7, false);
            string firstEightChars = Utils.Decode(base.data, subdirOffset, 8, false);

            if ("OLYMP".Equals(firstFiveChars) || "EPSON".Equals(firstFiveChars) || "AGFA".Equals(firstFourChars))
            {
                Trace.TraceInformation("Found an Olympus/Epson/Agfa directory.");
                // Olympus Makernote
                // Epson and Agfa use Olypus maker note standard, see:
                //     http://www.ozhiker.com/electronics/pjmt/jpeg_info/
                ProcessDirectory(
                    this.metadata.GetDirectory("com.drew.metadata.exif.OlympusDirectory"), processedDirectoryOffsets, subdirOffset + 8, tiffHeaderOffset);
            }
            else if (cameraModel != null && cameraModel.Trim().ToUpper().StartsWith("NIKON"))
            {
                if ("Nikon".Equals(Utils.Decode(base.data, subdirOffset, 5, false)))
                {
                    // There are two scenarios here:
                    // Type 1:
                    // :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon...........
                    // :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................
                    // Type 3:
                    // :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*...
                    // :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200
                    if (base.data[subdirOffset + 6] == 1)
                    {
                        Trace.TraceInformation("Found an Nykon Type 1 directory.");
                        ProcessDirectory(
                            this.metadata.GetDirectory("com.drew.metadata.exif.NikonType1Directory"), processedDirectoryOffsets, subdirOffset + 8, tiffHeaderOffset);
                    }
                    else if (base.data[subdirOffset + 6] == 2)
                    {
                        Trace.TraceInformation("Found an Nykon Type 2 directory.");
                        ProcessDirectory(
                            this.metadata.GetDirectory("com.drew.metadata.exif.NikonType2Directory"), processedDirectoryOffsets, subdirOffset + 18, subdirOffset + 10);
                    }
                    else
                    {
                        exifDirectory.HasError = true;
                        Trace.TraceError(
                            "Unsupported makernote for Nikon data ignored.");
                    }
                }
                else
                {
                    Trace.TraceInformation("Found an Nykon Type 2 directory.");
                    ProcessDirectory(
                        this.metadata.GetDirectory("com.drew.metadata.exif.NikonType2Directory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
                }
            }
            else if ("SONY CAM".Equals(firstEightChars) || "SONY DSC".Equals(firstEightChars))
            {
                Trace.TraceInformation("Found a Sony directory.");
                ProcessDirectory(
                    this.metadata.GetDirectory("com.drew.metadata.exif.SonyDirectory"), processedDirectoryOffsets, subdirOffset + 12, tiffHeaderOffset);
            }
            else if ("KDK".Equals(firstThreeChars))
            {
                Trace.TraceInformation("Found a Kodak directory.");
                ProcessDirectory(
                    this.metadata.GetDirectory("com.drew.metadata.exif.KodakDirectory"), processedDirectoryOffsets, subdirOffset + 20, tiffHeaderOffset);
            }


            else if ("Canon".ToUpper().Equals(cameraModel.ToUpper()))
            {
                Trace.TraceInformation("Found a Canon directory.");
                ProcessDirectory(
                    this.metadata.GetDirectory("com.drew.metadata.exif.CanonDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
            }
            else if (cameraModel != null && cameraModel.ToUpper().StartsWith("CASIO"))
            {
                if ("QVC\u0000\u0000\u0000".Equals(firstSixChars))
                {
                    Trace.TraceInformation("Found a Casion Type 2 directory.");
                    ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.CasioType2Directory"), processedDirectoryOffsets, subdirOffset + 6, tiffHeaderOffset);
                }
                else
                {
                    Trace.TraceInformation("Found a Casion Type 1 directory.");
                    ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.CasioType1Directory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
                }
            }
            else if ("FUJIFILM".Equals(firstEightChars) || "Fujifilm".ToUpper().Equals(cameraModel.ToUpper()))
            {
                Trace.TraceInformation("Found a Fujifilm directory.");
                // TODO make this field a passed parameter, to avoid threading issues
                bool byteOrderBefore = this.isMotorollaByteOrder;
                // bug in fujifilm makernote ifd means we temporarily use Intel byte ordering
                this.isMotorollaByteOrder = false;
                // the 4 bytes after "FUJIFILM" in the makernote point to the start of the makernote
                // IFD, though the lcOffset is relative to the start of the makernote, not the TIFF
                // lcHeader (like everywhere else)
                int ifdStart = subdirOffset + Get32Bits(subdirOffset + 8);
                ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.FujifilmDirectory"), processedDirectoryOffsets, ifdStart, tiffHeaderOffset);
                this.isMotorollaByteOrder = byteOrderBefore;
            }
            else if (cameraModel != null && cameraModel.ToUpper().StartsWith("MINOLTA"))
            {
                Trace.TraceInformation("Found a Minolta directory, will use Olympus directory.");
                // Cases seen with the model starting with MINOLTA in capitals seem to have a valid Olympus makernote
                // area that commences immediately.
                ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif. OlympusDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset);
            }
            else if ("KC".Equals(firstTwoChars) || "MINOL".Equals(firstFiveChars) || "MLY".Equals(firstThreeChars) || "+M+M+M+M".Equals(firstEightChars))
            {
                // This Konica data is not understood.  Header identified in accordance with information at this site:
                // http://www.ozhiker.com/electronics/pjmt/jpeg_info/minolta_mn.html
                // TODO determine how to process the information described at the above website
                Trace.TraceError("Unsupported Konica/Minolta data ignored.");
            }
            else if ("KYOCERA".Equals(firstSevenChars))
            {
                Trace.TraceInformation("Found a Kyocera directory");
                // http://www.ozhiker.com/electronics/pjmt/jpeg_info/kyocera_mn.html
                ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.KyoceraDirectory"), processedDirectoryOffsets, subdirOffset + 22, tiffHeaderOffset);
            }
            else if ("Panasonic\u0000\u0000\u0000".Equals(Utils.Decode(base.data, subdirOffset, 12, false)))
            {
                Trace.TraceInformation("Found a panasonic directory");
                // NON-Standard TIFF IFD Data using Panasonic Tags. There is no Next-IFD pointer after the IFD
                // Offsets are relative to the start of the TIFF lcHeader at the beginning of the EXIF segment
                // more information here: http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html
                ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.PanasonicDirectory"), processedDirectoryOffsets, subdirOffset + 12, tiffHeaderOffset);
            }
            else if ("AOC\u0000".Equals(firstFourChars))
            {
                Trace.TraceInformation("Found a Casio type 2 directory");
                // NON-Standard TIFF IFD Data using Casio Type 2 Tags
                // IFD has no Next-IFD pointer at end of IFD, and
                // Offsets are relative to the start of the current IFD tag, not the TIFF lcHeader
                // Observed for:
                // - Pentax ist D
                ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.CasioType2Directory"), processedDirectoryOffsets, subdirOffset + 6, subdirOffset);
            }
            else if (cameraModel != null && (cameraModel.ToUpper().StartsWith("PENTAX") || cameraModel.ToUpper().StartsWith("ASAHI")))
            {
                Trace.TraceInformation("Found a Pentax directory");
                // NON-Standard TIFF IFD Data using Pentax Tags
                // IFD has no Next-IFD pointer at end of IFD, and
                // Offsets are relative to the start of the current IFD tag, not the TIFF lcHeader
                // Observed for:
                // - PENTAX Optio 330
                // - PENTAX Optio 430
                ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.PentaxDirectory"), processedDirectoryOffsets, subdirOffset, subdirOffset);
            }
            else
            {
                // TODO how to store makernote data when it'str not from a supported camera model?
                Trace.TraceError("Unsupported directory data ignored.");
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Processes tag
        /// </summary>
        /// <param name="directory">the directory</param>
        /// <param name="aTagType">the tag type</param>
        /// <param name="tagValueOffset">the lcOffset value</param>
        /// <param name="componentCount">the component count</param>
        /// <param name="formatCode">the format code</param>
        private void ProcessTag(
            AbstractDirectory directory,
            int tagType,
            int tagValueOffset,
            int componentCount,
            int formatCode)
        {
            // Directory simply stores raw values
            // The display side uses a Descriptor class per directory to turn the raw values into 'pretty' descriptions
            switch (formatCode)
            {
            case FMT_UNDEFINED:
                Debug.Write("Found a tag made of bytes");
                // this includes exif user comments
                byte[] tagBytes  = new byte[componentCount];
                int    byteCount = componentCount * BYTES_PER_FORMAT[formatCode];
                for (int i = 0; i < byteCount; i++)
                {
                    tagBytes[i] = base.data[tagValueOffset + i];
                }
                directory.SetObject(tagType, tagBytes);
                break;

            case FMT_STRING:
                Debug.Write("Found a tag made of string");
                string lcStr = null;
                if (tagType == ExifDirectory.TAG_USER_COMMENT)
                {
                    lcStr =
                        ReadCommentString(
                            tagValueOffset,
                            componentCount,
                            formatCode);
                }
                else
                {
                    lcStr = ReadString(tagValueOffset, componentCount);
                }
                directory.SetObject(tagType, lcStr);
                break;

            case FMT_SRATIONAL:     //goto case FMT_URATIONAL;
            case FMT_URATIONAL:
                if (componentCount == 1)
                {
                    Debug.Write("Found a tag made of rational");
                    Rational rational = new Rational(Get32Bits(tagValueOffset), Get32Bits(tagValueOffset + 4));
                    directory.SetObject(tagType, rational);
                }
                else
                {
                    Debug.Write("Found a tag made of rationals");
                    Rational[] rationals = new Rational[componentCount];
                    for (int i = 0; i < componentCount; i++)
                    {
                        rationals[i] = new Rational(Get32Bits(tagValueOffset + (8 * i)), Get32Bits(tagValueOffset + 4 + (8 * i)));
                    }
                    directory.SetObject(tagType, rationals);
                }

                break;

            case FMT_SBYTE:     //goto case FMT_BYTE;
            case FMT_BYTE:
                if (componentCount == 1)
                {
                    Debug.Write("Found a tag made of byte");
                    // this may need to be a byte, but I think casting to int is fine
                    int b = base.data[tagValueOffset];
                    directory.SetObject(tagType, b);
                }
                else
                {
                    Debug.Write("Found a tag made of bytes but will use ints");
                    int[] bytes = new int[componentCount];
                    for (int i = 0; i < componentCount; i++)
                    {
                        bytes[i] = base.data[tagValueOffset + i];
                    }
                    directory.SetIntArray(tagType, bytes);
                }
                break;

            case FMT_SINGLE:     //goto case FMT_DOUBLE;
            case FMT_DOUBLE:
                if (componentCount == 1)
                {
                    Debug.Write("Found a tag made of double but will use int");
                    int i = base.data[tagValueOffset];
                    directory.SetObject(tagType, i);
                }
                else
                {
                    Debug.Write("Found a tag made of doubles but will use ints");
                    int[] ints = new int[componentCount];
                    for (int i = 0; i < componentCount; i++)
                    {
                        ints[i] = base.data[tagValueOffset + i];
                    }
                    directory.SetIntArray(tagType, ints);
                }
                break;

            case FMT_USHORT:     //goto case FMT_SSHORT;
            case FMT_SSHORT:
                if (componentCount == 1)
                {
                    Debug.Write("Found a tag made of short but will use int");
                    int i = Get16Bits(tagValueOffset);
                    directory.SetObject(tagType, i);
                }
                else
                {
                    Debug.Write("Found a tag made of shorts but will use ints");
                    int[] ints = new int[componentCount];
                    for (int i = 0; i < componentCount; i++)
                    {
                        ints[i] = Get16Bits(tagValueOffset + (i * 2));
                    }
                    directory.SetIntArray(tagType, ints);
                }
                break;

            case FMT_SLONG:     //goto case FMT_ULONG;
            case FMT_ULONG:
                if (componentCount == 1)
                {
                    Debug.Write("Found a tag made of long but will use int");
                    int i = Get32Bits(tagValueOffset);
                    directory.SetObject(tagType, i);
                }
                else
                {
                    Debug.Write("Found a tag made of longs but will use ints");
                    int[] ints = new int[componentCount];
                    for (int i = 0; i < componentCount; i++)
                    {
                        ints[i] = Get32Bits(tagValueOffset + (i * 4));
                    }
                    directory.SetIntArray(tagType, ints);
                }
                break;

            default:
                Trace.TraceWarning("Unknown format code " + formatCode + " for tag " + tagType);
                break;
            }
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="aDirectory">a base.directory</param>
 public PanasonicDescriptor(AbstractDirectory aDirectory)
     : base(aDirectory)
 {
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="aDirectory">a base.directory</param>
 public OlympusDescriptor(AbstractDirectory aDirectory) : base(aDirectory)
 {
 }
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="directory">a directory</param>
 public KodakDescriptor(AbstractDirectory directory)
     : base(directory)
 {
 }
Ejemplo n.º 28
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="aDirectory">a base.directory</param>
 public FujifilmDescriptor(AbstractDirectory aDirectory) : base(aDirectory)
 {
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Extracts aMetadata
        /// </summary>
        /// <param name="aMetadata">where to add aMetadata</param>
        /// <returns>the aMetadata found</returns>
        public override Metadata Extract(Metadata aMetadata)
        {
            if (base.data == null)
            {
                return(aMetadata);
            }

            AbstractDirectory lcDirectory = aMetadata.GetDirectory("com.drew.metadata.jpeg.JpegDirectory");

            try
            {
                // data precision
                int dataPrecision =
                    base.Get16Bits(JpegDirectory.TAG_JPEG_DATA_PRECISION);
                lcDirectory.SetObject(
                    JpegDirectory.TAG_JPEG_DATA_PRECISION,
                    dataPrecision);

                // process height
                int height = base.Get32Bits(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
                lcDirectory.SetObject(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT, height);

                // process width
                int width = base.Get32Bits(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
                lcDirectory.SetObject(JpegDirectory.TAG_JPEG_IMAGE_WIDTH, width);

                // number of components
                int numberOfComponents =
                    base.Get16Bits(JpegDirectory.TAG_JPEG_NUMBER_OF_COMPONENTS);
                lcDirectory.SetObject(
                    JpegDirectory.TAG_JPEG_NUMBER_OF_COMPONENTS,
                    numberOfComponents);

                // for each component, there are three bytes of data:
                // 1 - Component ID: 1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q
                // 2 - Sampling factors: bit 0-3 vertical, 4-7 horizontal
                // 3 - Quantization table number
                int offset = 6;
                for (int i = 0; i < numberOfComponents; i++)
                {
                    int           componentId             = base.Get16Bits(offset++);
                    int           samplingFactorByte      = base.Get16Bits(offset++);
                    int           quantizationTableNumber = base.Get16Bits(offset++);
                    JpegComponent lcJpegComponent         =
                        new JpegComponent(
                            componentId,
                            samplingFactorByte,
                            quantizationTableNumber);
                    lcDirectory.SetObject(
                        JpegDirectory.TAG_JPEG_COMPONENT_DATA_1 + i,
                        lcJpegComponent);
                }
            }
            catch (MetadataException me)
            {
                lcDirectory.HasError = true;
                Trace.TraceError("MetadataException: " + me.Message);
            }

            return(aMetadata);
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="base.directory">a base.directory</param>
 public NikonType2Descriptor(AbstractDirectory aDirectory)
     : base(aDirectory)
 {
 }
Ejemplo n.º 31
0
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="aDirectory">a base.directory</param>
 public KyoceraDescriptor(AbstractDirectory aDirectory)
     : base(aDirectory)
 {
 }
 /// <summary>
 /// Constructor of the object
 /// </summary>
 /// <param name="base.directory">a base.directory</param>
 public PentaxDescriptor(AbstractDirectory aDirectory)
     : base(aDirectory)
 {
 }