You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by da...@apache.org on 2011/11/28 06:46:46 UTC

svn commit: r1206983 - in /commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats: jpeg/JpegImageMetadata.java tiff/TiffField.java tiff/TiffImageMetadata.java

Author: damjan
Date: Mon Nov 28 05:46:45 2011
New Revision: 1206983

URL: http://svn.apache.org/viewvc?rev=1206983&view=rev
Log:
EXIF tag matching fixes.

Search all tags instead of just EXIF tags
when parsing TIFF metadata tags, and
simplify the directory type search.

Change TiffImageMetadata's findField() to
work like TiffField's getTag(). This means
it tries to do a directory match as well
as a tag match. Also an inexact directory
match is not even tried unless that tag
is unique among all our tags.

Test with other tools (Phatch, exiftool,
exif, Irfanview, PhotoME) shows
that this parsing is now consistent with them:
all of them also either ignore tags in
ambiguous directories, fail to parse them,
or interpret them potentially incorrectly.

Jira issue key: SANSELAN-21


Modified:
    commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageMetadata.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageMetadata.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageMetadata.java?rev=1206983&r1=1206982&r2=1206983&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageMetadata.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageMetadata.java Mon Nov 28 05:46:45 2011
@@ -53,39 +53,19 @@ public class JpegImageMetadata implement
     }
 
     public TiffField findEXIFValue(TagInfo tagInfo) {
-        TiffField field = findEXIFValue(tagInfo, true);
-        if (field == null) {
-            // In some cases, we want an exact directory match (such as GPS values).
-            // In other cases, we are more permissive (ie. with tags that may appear
-            // in a number of different directories, depending on the camera manufacturer, etc.
-            // TODO: Modify TagInfo class to include a "permissive/exact" flag.
-            field = findEXIFValue(tagInfo, false);
+        try {
+            return exif.findField(tagInfo);
+        } catch (ImageReadException cannotHappen) {
+            return null;
         }
-        return field;
     }
 
     public TiffField findEXIFValueWithExactMatch(TagInfo tagInfo) {
-        return findEXIFValue(tagInfo, true);
-    }
-
-    private TiffField findEXIFValue(TagInfo tagInfo, boolean requireDirectoryMatch) {
-        ArrayList items = getItems();
-        for (int i = 0; i < items.size(); i++) {
-            Object o = items.get(i);
-            if (!(o instanceof TiffImageMetadata.Item))
-                continue;
-
-            TiffImageMetadata.Item item = (TiffImageMetadata.Item) o;
-            TiffField field = item.getTiffField();
-            if (requireDirectoryMatch &&
-                    (field.directoryType != tagInfo.directoryType.directoryType)) {
-                continue;
-            }
-            if (field.tag == tagInfo.tag)
-                return field;
+        try {
+            return exif.findField(tagInfo, true);
+        } catch (ImageReadException cannotHappen) {
+            return null;
         }
-
-        return null;
     }
 
     /**

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java?rev=1206983&r1=1206982&r2=1206983&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffField.java Mon Nov 28 05:46:45 2011
@@ -120,6 +120,8 @@ public class TiffField implements TiffCo
     private static TagInfo getTag(int directoryType, int tag,
             List possibleMatches)
     {
+    	// Please keep this method in sync with TiffImageMetadata's findField()
+    	
         if (possibleMatches.size() < 1)
             return null;
         // else if (possibleMatches.size() == 1)
@@ -135,29 +137,7 @@ public class TiffField implements TiffCo
             if (tagInfo.directoryType == EXIF_DIRECTORY_UNKNOWN)
                 // pass
                 continue;
-            else if (directoryType == DIRECTORY_TYPE_EXIF
-                    && tagInfo.directoryType == EXIF_DIRECTORY_EXIF_IFD)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_INTEROPERABILITY
-                    && tagInfo.directoryType == EXIF_DIRECTORY_INTEROP_IFD)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_GPS
-                    && tagInfo.directoryType == EXIF_DIRECTORY_GPS)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_MAKER_NOTES
-                    && tagInfo.directoryType == EXIF_DIRECTORY_MAKER_NOTES)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_DIR_0
-                    && tagInfo.directoryType == TIFF_DIRECTORY_IFD0)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_DIR_1
-                    && tagInfo.directoryType == TIFF_DIRECTORY_IFD1)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_DIR_2
-                    && tagInfo.directoryType == TIFF_DIRECTORY_IFD2)
-                return tagInfo;
-            else if (directoryType == DIRECTORY_TYPE_DIR_3
-                    && tagInfo.directoryType == TIFF_DIRECTORY_IFD3)
+            else if (directoryType == tagInfo.directoryType.directoryType)
                 return tagInfo;
         }
 
@@ -271,7 +251,7 @@ public class TiffField implements TiffCo
     {
         Object key = new Integer(tag);
 
-        List possibleMatches = (List) EXIF_TAG_MAP.get(key);
+        List possibleMatches = (List) ALL_TAG_MAP.get(key);
 
         if (null == possibleMatches)
         {

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java?rev=1206983&r1=1206982&r2=1206983&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/formats/tiff/TiffImageMetadata.java Mon Nov 28 05:46:45 2011
@@ -19,12 +19,15 @@ package org.apache.sanselan.formats.tiff
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.sanselan.ImageReadException;
 import org.apache.sanselan.ImageWriteException;
 import org.apache.sanselan.common.ImageMetadata;
 import org.apache.sanselan.common.RationalNumber;
+import org.apache.sanselan.formats.tiff.constants.AllTagConstants;
 import org.apache.sanselan.formats.tiff.constants.TagInfo;
 import org.apache.sanselan.formats.tiff.constants.TiffConstants;
 import org.apache.sanselan.formats.tiff.constants.TiffDirectoryConstants;
@@ -38,12 +41,32 @@ public class TiffImageMetadata extends I
             TiffDirectoryConstants
 {
     public final TiffContents contents;
+    private static final Map tagCounts = countTags(AllTagConstants.ALL_TAGS);
 
     public TiffImageMetadata(final TiffContents contents)
     {
         this.contents = contents;
     }
 
+    private static final Map countTags(TagInfo tags[])
+    {
+        Map map = new Hashtable();
+
+        for (int i = 0; i < tags.length; i++)
+        {
+            TagInfo tag = tags[i];
+            Object key = new Integer(tag.tag);
+
+            Integer count = (Integer) map.get(key);
+            if (count == null)
+                map.put(key, new Integer(1));
+            else
+            	map.put(key, new Integer(count.intValue() + 1));
+        }
+
+        return map;
+    }
+
     public static class Directory extends ImageMetadata
             implements
                 ImageMetadata.IImageMetadataItem
@@ -230,14 +253,59 @@ public class TiffImageMetadata extends I
 
     public TiffField findField(TagInfo tagInfo) throws ImageReadException
     {
+        return findField(tagInfo, false);
+    }
+    
+    public TiffField findField(TagInfo tagInfo, boolean exactDirectoryMatch) throws ImageReadException
+    {
+    	// Please keep this method in sync with TiffField's getTag()
+    	Integer tagCount = (Integer)tagCounts.get(new Integer(tagInfo.tag));
+    	int tagsMatching = tagCount == null ? 0 : tagCount.intValue();
+    	
         ArrayList directories = getDirectories();
+        if (exactDirectoryMatch || tagInfo.directoryType != EXIF_DIRECTORY_UNKNOWN)
+        {
+            for (int i = 0; i < directories.size(); i++)
+            {
+                Directory directory = (Directory) directories.get(i);
+                if (directory.type == tagInfo.directoryType.directoryType) {
+                    TiffField field = directory.findField(tagInfo);
+                    if (field != null) {
+                    	return field;
+                    }
+                }
+            }
+            if (exactDirectoryMatch || tagsMatching > 1) {
+            	return null;
+            }
+            for (int i = 0; i < directories.size(); i++)
+            {
+                Directory directory = (Directory) directories.get(i);
+                if (tagInfo.directoryType.isImageDirectory() &&
+                		directory.type >= 0) {
+                    TiffField field = directory.findField(tagInfo);
+                    if (field != null) {
+                    	return field;
+                    }
+                } else if (!tagInfo.directoryType.isImageDirectory() &&
+                		directory.type < 0) {
+                    TiffField field = directory.findField(tagInfo);
+                    if (field != null) {
+                    	return field;
+                    }
+                }
+            }
+        }
+        
         for (int i = 0; i < directories.size(); i++)
         {
             Directory directory = (Directory) directories.get(i);
             TiffField field = directory.findField(tagInfo);
-            if (null != field)
-                return field;
+            if (field != null) {
+            	return field;
+            }
         }
+    	
         return null;
     }