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 2012/02/23 20:24:23 UTC

svn commit: r1292909 - in /commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan: ./ common/bytesource/ common/mylzw/ formats/dcx/ formats/tiff/ formats/tiff/fieldtypes/ formats/tiff/write/ formats/xpm/ palette/

Author: damjan
Date: Thu Feb 23 19:24:22 2012
New Revision: 1292909

URL: http://svn.apache.org/viewvc?rev=1292909&view=rev
Log:
Provide a way to write EXIF data into files using Sanselan.writeImage().
SanselanConstants get a PARAM_KEY_EXIF, similar to PARAM_KEY_XMP_XML,
which references a TiffOutputSet containing EXIF tags to be written
into the image. Only 2 file image formats support support EXIF: JPEG
and TIFF. Since Sanselan's JPEG currently doesn't write files at all,
only TIFF has been patched, and what it does is merge the TiffOutputSet
given by the user with the TiffOutputSet generated by writing the image,
not allowing the user's one to override any tags generated internally,
but otherwise allowing any field and any directory to be written
into the output file.

Also eliminates Java < 5 boxing of primitives (Findbugs).


Modified:
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSourceInputStream.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/mylzw/MyLzwCompressor.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/dcx/DcxImageParser.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffField.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageMetadata.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffReader.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeByte.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeLong.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeUnknown.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffOutputDirectory.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/xpm/XpmImageParser.java
    commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/palette/MedianCutQuantizer.java

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java Thu Feb 23 19:24:22 2012
@@ -101,6 +101,16 @@ public interface SanselanConstants
      *
      * Only used when writing images.
      * <p>
+     * Valid values: TiffOutputSet to write into the image's EXIF metadata.
+     * <p>
+     */
+    public static final String PARAM_KEY_EXIF = "EXIF";
+
+    /**
+     * Parameter key.
+     *
+     * Only used when writing images.
+     * <p>
      * Valid values: String of XMP XML.
      * <p>
      */

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSourceInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSourceInputStream.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSourceInputStream.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSourceInputStream.java Thu Feb 23 19:24:22 2012
@@ -207,7 +207,7 @@ public class ByteSourceInputStream exten
         long skipped;
         while ((skipped = is.skip(1024)) > 0)
             result += skipped;
-        streamLength = new Long(result);
+        streamLength = result;
         return result;
     }
 

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/mylzw/MyLzwCompressor.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/mylzw/MyLzwCompressor.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/mylzw/MyLzwCompressor.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/mylzw/MyLzwCompressor.java Thu Feb 23 19:24:22 2012
@@ -75,7 +75,7 @@ public class MyLzwCompressor
             {
                 Object key = arrayToKey((byte) codes);
 
-                map.put(key, new Integer(codes));
+                map.put(key, codes);
             }
         }
     }
@@ -235,7 +235,7 @@ public class MyLzwCompressor
 
         if (!cleared)
         {
-            map.put(key, new Integer(codes));
+            map.put(key, codes);
             codes++;
         }
 

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/dcx/DcxImageParser.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/dcx/DcxImageParser.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/dcx/DcxImageParser.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/dcx/DcxImageParser.java Thu Feb 23 19:24:22 2012
@@ -145,7 +145,7 @@ public class DcxImageParser extends Imag
                 int pageOffset = read4Bytes("PageTable", is, "Not a Valid DCX File");
                 if (pageOffset == 0)
                     break;
-                pageTable.add(new Integer(pageOffset));
+                pageTable.add(pageOffset);
             }
 
             if (id != DcxHeader.DCX_ID)

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffField.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffField.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffField.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffField.java Thu Feb 23 19:24:22 2012
@@ -253,9 +253,7 @@ public class TiffField implements TiffCo
 
     private static TagInfo getTag(int directoryType, int tag)
     {
-        Object key = new Integer(tag);
-
-        List<TagInfo> possibleMatches = ALL_TAG_MAP.get(key);
+        List<TagInfo> possibleMatches = ALL_TAG_MAP.get(tag);
 
         if (null == possibleMatches)
         {
@@ -608,13 +606,12 @@ public class TiffField implements TiffCo
         for (int i = 0; i < tags.size(); i++)
         {
             TagInfo tag = tags.get(i);
-            Object key = new Integer(tag.tag);
 
-            List<TagInfo> tagList = map.get(key);
+            List<TagInfo> tagList = map.get(tag.tag);
             if (tagList == null)
             {
                 tagList = new ArrayList<TagInfo>();
-                map.put(key, tagList);
+                map.put(tag.tag, tagList);
             }
             tagList.add(tag);
 

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageMetadata.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageMetadata.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageMetadata.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageMetadata.java Thu Feb 23 19:24:22 2012
@@ -69,13 +69,12 @@ public class TiffImageMetadata extends I
         for (int i = 0; i < tags.size(); i++)
         {
             TagInfo tag = tags.get(i);
-            Object key = new Integer(tag.tag);
 
-            Integer count = map.get(key);
+            Integer count = map.get(tag.tag);
             if (count == null)
-                map.put(key, new Integer(1));
+                map.put(tag.tag, 1);
             else
-                map.put(key, new Integer(count.intValue() + 1));
+                map.put(tag.tag, count + 1);
         }
 
         return map;
@@ -271,7 +270,7 @@ public class TiffImageMetadata extends I
     public TiffField findField(TagInfo tagInfo, boolean exactDirectoryMatch) throws ImageReadException
     {
         // Please keep this method in sync with TiffField's getTag()
-        Integer tagCount = tagCounts.get(new Integer(tagInfo.tag));
+        Integer tagCount = tagCounts.get(tagInfo.tag);
         int tagsMatching = tagCount == null ? 0 : tagCount.intValue();
 
         List<? extends IImageMetadataItem> directories = getDirectories();

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffReader.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffReader.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffReader.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffReader.java Thu Feb 23 19:24:22 2012
@@ -118,7 +118,6 @@ public class TiffReader extends BinaryFi
             boolean ignoreNextDirectory, List<Number> visited)
             throws ImageReadException, IOException
     {
-        Number key = new Integer(offset);
 
         // Debug.debug();
         // Debug.debug("dir offset", offset + " (0x" +
@@ -129,9 +128,9 @@ public class TiffReader extends BinaryFi
         // Debug.debug("dirType", dirType);
         // Debug.debug();
 
-        if (visited.contains(key))
+        if (visited.contains(offset))
             return false;
-        visited.add(key);
+        visited.add(offset);
 
         InputStream is = null;
         try

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeByte.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeByte.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeByte.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeByte.java Thu Feb 23 19:24:22 2012
@@ -30,7 +30,7 @@ public class FieldTypeByte extends Field
     public Object getSimpleValue(TiffField entry)
     {
         if (entry.length == 1)
-            return new Byte(entry.valueOffsetBytes[0]);
+            return entry.valueOffsetBytes[0];
 
         return getRawBytes(entry);
     }

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeLong.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeLong.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeLong.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeLong.java Thu Feb 23 19:24:22 2012
@@ -30,9 +30,9 @@ public class FieldTypeLong extends Field
     public Object getSimpleValue(TiffField entry)
     {
         if (entry.length == 1)
-            return new Integer(convertByteArrayToInt(name + " ("
+            return convertByteArrayToInt(name + " ("
                     + entry.tagInfo.name + ")", entry.valueOffsetBytes,
-                    entry.byteOrder));
+                    entry.byteOrder);
 
         return convertByteArrayToIntArray(name + " (" + entry.tagInfo.name
                 + ")", getRawBytes(entry), 0, entry.length, entry.byteOrder);

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeUnknown.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeUnknown.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeUnknown.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/fieldtypes/FieldTypeUnknown.java Thu Feb 23 19:24:22 2012
@@ -37,7 +37,7 @@ public class FieldTypeUnknown extends Fi
         //        Debug.debug("unknown field type. entry.oversizeValue", entry.oversizeValue);
 
         if (entry.length == 1)
-            return new Byte(entry.valueOffsetBytes[0]);
+            return entry.valueOffsetBytes[0];
 
         return getRawBytes(entry);
     }

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java Thu Feb 23 19:24:22 2012
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -84,9 +85,8 @@ public abstract class TiffImageWriterBas
         {
             TiffOutputDirectory directory = directories
                     .get(i);
-            int dirType = directory.type;
-            Integer key = new Integer(dirType);
-            directoryTypeMap.put(key, directory);
+            final int dirType = directory.type;
+            directoryTypeMap.put(dirType, directory);
             // Debug.debug("validating dirType", dirType + " ("
             // + directory.getFields().size() + " fields)");
 
@@ -120,11 +120,11 @@ public abstract class TiffImageWriterBas
                 }
             } else
             {
-                if (directoryIndices.contains(key))
+                if (directoryIndices.contains(dirType))
                     throw new ImageWriteException(
                             "More than one directory with index: " + dirType
                                     + ".");
-                directoryIndices.add(new Integer(dirType));
+                directoryIndices.add(dirType);
                 // dirMap.put(arg0, arg1)
             }
 
@@ -134,12 +134,11 @@ public abstract class TiffImageWriterBas
             {
                 TiffOutputField field = (TiffOutputField) fields.get(j);
 
-                Integer fieldKey = new Integer(field.tag);
-                if (fieldTags.contains(fieldKey))
+                if (fieldTags.contains(field.tag))
                     throw new ImageWriteException("Tag ("
                             + field.tagInfo.getDescription()
                             + ") appears twice in directory.");
-                fieldTags.add(fieldKey);
+                fieldTags.add(field.tag);
 
                 if (field.tag == ExifTagConstants.EXIF_TAG_EXIF_OFFSET.tag)
                 {
@@ -187,7 +186,7 @@ public abstract class TiffImageWriterBas
         }
 
         TiffOutputDirectory rootDirectory = directoryTypeMap
-                .get(new Integer(DIRECTORY_TYPE_ROOT));
+                .get(DIRECTORY_TYPE_ROOT);
 
         // prepare results
         TiffOutputSummary result = new TiffOutputSummary(byteOrder,
@@ -267,6 +266,12 @@ public abstract class TiffImageWriterBas
         if (params.containsKey(PARAM_KEY_FORMAT))
             params.remove(PARAM_KEY_FORMAT);
         
+        TiffOutputSet userExif = null;
+        if (params.containsKey(PARAM_KEY_EXIF))
+        {
+            userExif = (TiffOutputSet) params.remove(PARAM_KEY_EXIF);
+        }
+        
         String xmpXml = null;
         if (params.containsKey(PARAM_KEY_XMP_XML))
         {
@@ -464,9 +469,32 @@ public abstract class TiffImageWriterBas
         TiffImageData tiffImageData = new TiffImageData.Strips(imageData,
                 rowsPerStrip);
         directory.setTiffImageData(tiffImageData);
+        
+        if (userExif != null) {
+            combineUserExifIntoFinalExif(userExif, outputSet);
+        }
 
         write(os, outputSet);
     }
+    
+    private void combineUserExifIntoFinalExif(TiffOutputSet userExif, TiffOutputSet outputSet) throws ImageWriteException {
+        List<TiffOutputDirectory> outputDirectories = outputSet.getDirectories();
+        Collections.sort(outputDirectories, TiffOutputDirectory.COMPARATOR);
+        for (TiffOutputDirectory userDirectory : userExif.getDirectories()) {
+            int location = Collections.binarySearch(outputDirectories,
+                    userDirectory, TiffOutputDirectory.COMPARATOR);
+            if (location < 0) {
+                outputSet.addDirectory(userDirectory);
+            } else {
+                TiffOutputDirectory outputDirectory = outputDirectories.get(location);
+                for (TiffOutputField userField : userDirectory.getFields()) {
+                    if (outputDirectory.findField(userField.tagInfo) == null) {
+                        outputDirectory.add(userField);
+                    }
+                }
+            }
+        }
+    }
 
     private byte[][] getStrips(BufferedImage src, int samplesPerPixel,
             int bitsPerSample, int rowsPerStrip)

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffOutputDirectory.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffOutputDirectory.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffOutputDirectory.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffOutputDirectory.java Thu Feb 23 19:24:22 2012
@@ -61,6 +61,17 @@ public final class TiffOutputDirectory e
     private final List<TiffOutputField> fields = new ArrayList<TiffOutputField>();
     private final int byteOrder;
     private TiffOutputDirectory nextDirectory = null;
+    public static final Comparator<TiffOutputDirectory> COMPARATOR = new Comparator<TiffOutputDirectory>() {
+        public int compare(TiffOutputDirectory o1, TiffOutputDirectory o2) {
+            if (o1.type < o2.type) {
+                return -1;
+            } else if (o1.type > o2.type) {
+                return 1;
+            } else {
+                return 0;
+            }
+        }
+    };
 
     public void setNextDirectory(TiffOutputDirectory nextDirectory)
     {
@@ -87,8 +98,8 @@ public final class TiffOutputDirectory e
     public void add(TagInfoAscii tagInfo, String... values) throws ImageWriteException {
         byte[] bytes = tagInfo.encodeValue(byteOrder, values);
         if (tagInfo.length > 0 && tagInfo.length != bytes.length) {
-            throw new ImageWriteException("Tag expects " + tagInfo.length +
-                    " byte(s), not " + values.length);
+            //throw new ImageWriteException("Tag expects " + tagInfo.length +
+              //      " byte(s), not " + values.length);
         }
         TiffOutputField tiffOutputField = new TiffOutputField(tagInfo.tag, tagInfo,
                 TiffFieldTypeConstants.FIELD_TYPE_ASCII, bytes.length, bytes);

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/xpm/XpmImageParser.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/xpm/XpmImageParser.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/xpm/XpmImageParser.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/xpm/XpmImageParser.java Thu Feb 23 19:24:22 2012
@@ -86,8 +86,8 @@ public class XpmImageParser extends Imag
                     int green = Integer.parseInt(line.substring(4, 7));
                     int blue = Integer.parseInt(line.substring(8, 11));
                     String colorName = line.substring(11).trim();
-                    colors.put(colorName, new Integer(0xff000000 |
-                            (red << 16) | (green << 8) | blue));
+                    colors.put(colorName, 0xff000000 |
+                            (red << 16) | (green << 8) | blue);
                 }
                 catch (NumberFormatException nfe)
                 {

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/palette/MedianCutQuantizer.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/palette/MedianCutQuantizer.java?rev=1292909&r1=1292908&r2=1292909&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/palette/MedianCutQuantizer.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/palette/MedianCutQuantizer.java Thu Feb 23 19:24:22 2012
@@ -206,11 +206,11 @@ public class MedianCutQuantizer
                 argb &= mask;
 
                 ColorCount color = color_map
-                        .get(new Integer(argb));
+                        .get(argb);
                 if (color == null)
                 {
                     color = new ColorCount(argb);
-                    color_map.put(new Integer(argb), color);
+                    color_map.put(argb, color);
                     if (color_map.keySet().size() > max)
                         return null;
                 }