You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by me...@apache.org on 2012/09/19 15:06:12 UTC

svn commit: r1387576 - in /xmlgraphics/commons/branches/Temp_URI_Resolution: ./ src/java/org/apache/xmlgraphics/image/writer/ src/java/org/apache/xmlgraphics/image/writer/imageio/ src/java/org/apache/xmlgraphics/image/writer/internal/ test/java/org/apa...

Author: mehdi
Date: Wed Sep 19 13:06:11 2012
New Revision: 1387576

URL: http://svn.apache.org/viewvc?rev=1387576&view=rev
Log:
Merged in trunk@1387571

Added:
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ResolutionUnit.java
      - copied unchanged from r1387571, xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/writer/ResolutionUnit.java
    xmlgraphics/commons/branches/Temp_URI_Resolution/test/java/org/apache/xmlgraphics/image/writer/ResolutionTestCase.java
      - copied unchanged from r1387571, xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/writer/ResolutionTestCase.java
Modified:
    xmlgraphics/commons/branches/Temp_URI_Resolution/   (props changed)
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterParams.java
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistry.java
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter.java
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWriter.java
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriter.java
    xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.java

Propchange: xmlgraphics/commons/branches/Temp_URI_Resolution/
------------------------------------------------------------------------------
  Merged /xmlgraphics/commons/trunk:r1365923-1387571

Modified: xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterParams.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterParams.java?rev=1387576&r1=1387575&r2=1387576&view=diff
==============================================================================
--- xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterParams.java (original)
+++ xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterParams.java Wed Sep 19 13:06:11 2012
@@ -19,6 +19,7 @@
 
 package org.apache.xmlgraphics.image.writer;
 
+
 /**
  * Parameters for the encoder which is accessed through the
  * ImageWriter interface.
@@ -27,10 +28,18 @@ package org.apache.xmlgraphics.image.wri
  */
 public class ImageWriterParams {
 
-    private Integer resolution;
+    /** Forces a single strip for the whole image. */
+    public static final int SINGLE_STRIP = -1;
+    /** Used for generating exactly one strip for each row */
+    public static final int ONE_ROW_PER_STRIP = 1;
+
+    private Integer xResolution = null;
+    private Integer yResolution = null;
     private Float jpegQuality;
     private Boolean jpegForceBaseline;
     private String compressionMethod;
+    private ResolutionUnit resolutionUnit = ResolutionUnit.INCH;
+    private int rowsPerStrip = ONE_ROW_PER_STRIP;
 
     /**
      * Default constructor.
@@ -40,10 +49,17 @@ public class ImageWriterParams {
     }
 
     /**
+     * @return true if resolution has been set
+     */
+    public boolean hasResolution() {
+        return getXResolution() != null && getYResolution() != null;
+    }
+
+    /**
      * @return the image resolution in dpi, or null if undefined
      */
     public Integer getResolution() {
-        return this.resolution;
+        return getXResolution();
     }
 
     /**
@@ -68,11 +84,13 @@ public class ImageWriterParams {
     }
 
     /**
-     * Sets the target resolution of the bitmap image to be written.
-     * @param dpi the resolution in dpi
-     */
-    public void setResolution(int dpi) {
-        this.resolution = new Integer(dpi);
+     * Sets the target resolution of the bitmap image to be written
+     * (sets both the horizontal and vertical resolution to the same value).
+     * @param resolution the resolution
+     */
+    public void setResolution(int resolution) {
+        setXResolution(resolution);
+        setYResolution(resolution);
     }
 
     /**
@@ -92,4 +110,87 @@ public class ImageWriterParams {
     public void setCompressionMethod(String method) {
         this.compressionMethod = method;
     }
-}
+
+    /**
+     * Checks if image is single strip (required by some fax processors).
+     * @return true if one row per strip.
+     */
+    public boolean isSingleStrip() {
+        return rowsPerStrip == SINGLE_STRIP;
+    }
+
+    /**
+     * Convenience method to set rows per strip to single strip,
+     * otherwise sets to one row per strip.
+     * @param isSingle true if a single strip shall be produced, false if multiple strips are ok
+     */
+    public void setSingleStrip(boolean isSingle) {
+        rowsPerStrip = isSingle ? SINGLE_STRIP : ONE_ROW_PER_STRIP;
+    }
+
+    /**
+     * Sets the rows per strip (default is one row per strip);
+     * if set to -1 (single strip), will use height of the current page,
+     * required by some fax processors.
+     * @param rowsPerStrip the value to set.
+     */
+    public void setRowsPerStrip(int rowsPerStrip) {
+        this.rowsPerStrip = rowsPerStrip;
+    }
+
+    /**
+     * The number of rows per strip of the TIFF image, default 1.  A value of -1
+     * indicates a single strip per page will be used and RowsPerStrip will be set
+     * to image height for the associated page.
+     * @return the number of rows per strip, default 1.
+     */
+    public int getRowsPerStrip() {
+        return rowsPerStrip;
+    }
+
+    /**
+     * Returns the unit in which resolution values are given (ex. units per inch).
+     * @return the resolution unit.
+     */
+    public ResolutionUnit getResolutionUnit() {
+        return resolutionUnit;
+    }
+
+    /**
+     * Sets the resolution unit of the image for calculating resolution.
+     * @param resolutionUnit the resolution unit (inches, centimeters etc.)
+     */
+    public void setResolutionUnit(ResolutionUnit resolutionUnit) {
+        this.resolutionUnit = resolutionUnit;
+    }
+
+    /**
+     * @return the horizontal image resolution in the current resolution unit, or null if undefined
+     */
+    public Integer getXResolution() {
+        return xResolution;
+    }
+
+    /**
+     * Sets the target horizontal resolution of the bitmap image to be written.
+     * @param resolution the resolution value
+     */
+    public void setXResolution(int resolution) {
+        xResolution = Integer.valueOf(resolution);
+    }
+
+    /**
+     * @return the vertical image resolution in the current resolution unit, or null if undefined
+     */
+    public Integer getYResolution() {
+        return yResolution;
+    }
+
+    /**
+     * Sets the target vertical resolution of the bitmap image to be written.
+     * @param resolution the resolution value
+     */
+    public void setYResolution(int resolution) {
+        yResolution = Integer.valueOf(resolution);
+    }
+}
\ No newline at end of file

Modified: xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistry.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistry.java?rev=1387576&r1=1387575&r2=1387576&view=diff
==============================================================================
--- xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistry.java (original)
+++ xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/ImageWriterRegistry.java Wed Sep 19 13:06:11 2012
@@ -30,16 +30,15 @@ import java.util.Properties;
 import org.apache.xmlgraphics.util.Service;
 
 /**
- * Registry for ImageWriter implementations. They are primarily registered through the "Service
- * Provider" mechanism.
- * @see org.apache.xmlgraphics.util.Service
+ * Registry for {@link ImageWriter} implementations.
  */
 public class ImageWriterRegistry {
 
-    private static ImageWriterRegistry instance;
+    private static volatile ImageWriterRegistry instance;
 
-    private Map imageWriterMap = new java.util.HashMap();
-    private Map preferredOrder;
+    private Map<String, List<ImageWriter>> imageWriterMap
+            = new java.util.HashMap<String, List<ImageWriter>>();
+    private Map<String, Integer> preferredOrder;
 
     /**
      * Default constructor. The default preferred order for the image writers is loaded from the
@@ -61,7 +60,7 @@ public class ImageWriterRegistry {
                             + ioe.getMessage());
             }
         }
-        this.preferredOrder = props;
+        setPreferredOrder(props);
         setup();
     }
 
@@ -73,10 +72,19 @@ public class ImageWriterRegistry {
      * @param preferredOrder the map of order properties used to order the plug-ins
      */
     public ImageWriterRegistry(Properties preferredOrder) {
-        this.preferredOrder = preferredOrder;
+        setPreferredOrder(preferredOrder);
         setup();
     }
 
+    private void setPreferredOrder(Properties preferredOrder) {
+        Map<String, Integer> order = new java.util.HashMap<String, Integer>();
+        for (Map.Entry<Object, Object> entry : preferredOrder.entrySet()) {
+            order.put(entry.getKey().toString(),
+                    Integer.parseInt(entry.getValue().toString()));
+        }
+        this.preferredOrder = order;
+    }
+
     /** @return a singleton instance of the ImageWriterRegistry. */
     public static ImageWriterRegistry getInstance() {
         if (instance == null) {
@@ -95,7 +103,7 @@ public class ImageWriterRegistry {
 
     private int getPriority(ImageWriter writer) {
         String key = writer.getClass().getName();
-        Object value = preferredOrder.get(key);
+        Integer value = preferredOrder.get(key);
         while (value == null) {
             int pos = key.lastIndexOf(".");
             if (pos < 0) {
@@ -104,7 +112,7 @@ public class ImageWriterRegistry {
             key = key.substring(0, pos);
             value = preferredOrder.get(key);
         }
-        return (value != null) ? Integer.parseInt(value.toString()) : 0;
+        return (value != null) ? value.intValue() : 0;
     }
 
     /**
@@ -118,7 +126,7 @@ public class ImageWriterRegistry {
 
         String key = writer.getClass().getName();
         // Register the priority to preferredOrder; overwrite original priority if exists
-        preferredOrder.put(key, String.valueOf(priority));
+        preferredOrder.put(key, priority);
 
         register(writer);
     }
@@ -128,18 +136,17 @@ public class ImageWriterRegistry {
      * target MIME type has already been registered, it is placed in an array based on priority.
      * @param writer the ImageWriter instance to register.
      */
-    public void register(ImageWriter writer) {
-        List entries = (List)imageWriterMap.get(writer.getMIMEType());
+    public synchronized void register(ImageWriter writer) {
+        List<ImageWriter> entries = imageWriterMap.get(writer.getMIMEType());
         if (entries == null) {
-            entries = new java.util.ArrayList();
+            entries = new java.util.ArrayList<ImageWriter>();
             imageWriterMap.put(writer.getMIMEType(), entries);
         }
 
         int priority = getPriority(writer);
-
-        ListIterator li = entries.listIterator();
+        ListIterator<ImageWriter> li = entries.listIterator();
         while (li.hasNext()) {
-            ImageWriter w = (ImageWriter)li.next();
+            ImageWriter w = li.next();
             if (getPriority(w) < priority) {
                 li.previous();
                 break;
@@ -154,14 +161,14 @@ public class ImageWriterRegistry {
      * @return a functional ImageWriter instance handling the desired output format or
      *         null if none can be found.
      */
-    public ImageWriter getWriterFor(String mime) {
-        List entries = (List)imageWriterMap.get(mime);
+    public synchronized ImageWriter getWriterFor(String mime) {
+        List<ImageWriter> entries = imageWriterMap.get(mime);
         if (entries == null) {
             return null;
         }
-        Iterator iter = entries.iterator();
+        Iterator<ImageWriter> iter = entries.iterator();
         while (iter.hasNext()) {
-            ImageWriter writer = (ImageWriter)iter.next();
+            ImageWriter writer = iter.next();
             if (writer.isFunctional()) {
                 return writer;
             }

Modified: xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter.java?rev=1387576&r1=1387575&r2=1387576&view=diff
==============================================================================
--- xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter.java (original)
+++ xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOImageWriter.java Wed Sep 19 13:06:11 2012
@@ -40,6 +40,8 @@ import org.w3c.dom.NodeList;
 import org.apache.xmlgraphics.image.writer.ImageWriter;
 import org.apache.xmlgraphics.image.writer.ImageWriterParams;
 import org.apache.xmlgraphics.image.writer.MultiImageWriter;
+import org.apache.xmlgraphics.image.writer.ResolutionUnit;
+import org.apache.xmlgraphics.util.UnitConv;
 
 /**
  * ImageWriter implementation that uses Image I/O to write images.
@@ -48,6 +50,10 @@ import org.apache.xmlgraphics.image.writ
  */
 public class ImageIOImageWriter implements ImageWriter, IIOWriteWarningListener {
 
+    private static final String DIMENSION = "Dimension";
+    private static final String VERTICAL_PIXEL_SIZE = "VerticalPixelSize";
+    private static final String HORIZONTAL_PIXEL_SIZE = "HorizontalPixelSize";
+
     private static final String STANDARD_METADATA_FORMAT = "javax_imageio_1.0";
 
     private String targetMIME;
@@ -60,16 +66,12 @@ public class ImageIOImageWriter implemen
         this.targetMIME = mime;
     }
 
-    /**
-     * @see ImageWriter#writeImage(java.awt.image.RenderedImage, java.io.OutputStream)
-     */
+    /** {@inheritDoc} */
     public void writeImage(RenderedImage image, OutputStream out) throws IOException {
         writeImage(image, out, null);
     }
 
-    /**
-     * @see ImageWriter#writeImage(java.awt.image.RenderedImage, java.io.OutputStream, ImageWriterParams)
-     */
+    /** {@inheritDoc} */
     public void writeImage(RenderedImage image, OutputStream out,
             ImageWriterParams params)
                 throws IOException {
@@ -93,7 +95,7 @@ public class ImageIOImageWriter implemen
                     type, iwParam);
             //meta might be null for some JAI codecs as they don't support metadata
             if (params != null && meta != null) {
-                meta = updateMetadata(meta, params);
+                meta = updateMetadata(image, meta, params);
             }
 
             //Write image
@@ -108,10 +110,10 @@ public class ImageIOImageWriter implemen
     }
 
     private javax.imageio.ImageWriter getIIOImageWriter() {
-        Iterator iter = ImageIO.getImageWritersByMIMEType(getMIMEType());
+        Iterator<javax.imageio.ImageWriter> iter = ImageIO.getImageWritersByMIMEType(getMIMEType());
         javax.imageio.ImageWriter iiowriter = null;
         if (iter.hasNext()) {
-            iiowriter = (javax.imageio.ImageWriter)iter.next();
+            iiowriter = iter.next();
         }
         if (iiowriter == null) {
             throw new UnsupportedOperationException("No ImageIO codec for writing "
@@ -141,41 +143,82 @@ public class ImageIOImageWriter implemen
 
     /**
      * Updates the metadata information based on the parameters to this writer.
+     * @param image the current image being rendered
      * @param meta the metadata
      * @param params the parameters
      * @return the updated metadata
      */
-    protected IIOMetadata updateMetadata(IIOMetadata meta, ImageWriterParams params) {
-        if (meta.isStandardMetadataFormatSupported()) {
-            IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(STANDARD_METADATA_FORMAT);
-            IIOMetadataNode dim = getChildNode(root, "Dimension");
-            IIOMetadataNode child;
-            if (params.getResolution() != null) {
-                child = getChildNode(dim, "HorizontalPixelSize");
-                if (child == null) {
-                    child = new IIOMetadataNode("HorizontalPixelSize");
-                    dim.appendChild(child);
-                }
-                child.setAttribute("value",
-                        Double.toString(params.getResolution().doubleValue() / 25.4));
-                child = getChildNode(dim, "VerticalPixelSize");
-                if (child == null) {
-                    child = new IIOMetadataNode("VerticalPixelSize");
-                    dim.appendChild(child);
-                }
-                child.setAttribute("value",
-                        Double.toString(params.getResolution().doubleValue() / 25.4));
-            }
-            try {
-                meta.mergeTree(STANDARD_METADATA_FORMAT, root);
-            } catch (IIOInvalidTreeException e) {
-                throw new RuntimeException("Cannot update image metadata: "
-                            + e.getMessage());
+    protected IIOMetadata updateMetadata(RenderedImage image, IIOMetadata meta,
+                ImageWriterParams params) {
+        if (meta.isStandardMetadataFormatSupported() && params.getResolution() != null) {
+
+            //NOTE: There are several bugs in ImageIO codecs concerning resolution handling
+            //http://www.tracemodeler.com/articles/aging-bugs-and-setting-dpi-with-java-image-io/
+
+            float multiplier = (ResolutionUnit.CENTIMETER == params.getResolutionUnit()) ? 10f : UnitConv.IN2MM;
+            double pixelWidthInMillimeters = multiplier / params.getXResolution().doubleValue();
+            double pixelHeightInMillimeters = multiplier / params.getYResolution().doubleValue();
+
+            //Try with the right value as per the ImageIO spec
+            updatePixelSize(meta, pixelWidthInMillimeters, pixelHeightInMillimeters);
+
+            //Check the merge result
+            double checkMerged = getHorizontalPixelSize(meta);
+            if (!equals(checkMerged, pixelWidthInMillimeters, 0.00001)) {
+                //Merging bug in Sun/Oracle JRE encountered
+                //Try compensation strategy for PNG bug:
+                //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5106305
+                double horzValue = 1 / pixelWidthInMillimeters;
+                double vertValue = 1 / pixelHeightInMillimeters;
+                updatePixelSize(meta, horzValue, vertValue);
             }
         }
         return meta;
     }
 
+    private static boolean equals(double d1, double d2, double maxDelta) {
+        return Math.abs(d1 - d2) <= maxDelta;
+    }
+
+    private double getHorizontalPixelSize(IIOMetadata meta) {
+        double result = 0;
+        IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(STANDARD_METADATA_FORMAT);
+        IIOMetadataNode dim = getChildNode(root, DIMENSION);
+        if (dim != null) {
+            IIOMetadataNode horz = getChildNode(dim, HORIZONTAL_PIXEL_SIZE);
+            if (horz != null) {
+                result = Double.parseDouble(horz.getAttribute("value"));
+            }
+        }
+        return result;
+    }
+
+    private void updatePixelSize(IIOMetadata meta, double horzValue, double vertValue) {
+        IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(STANDARD_METADATA_FORMAT);
+        IIOMetadataNode dim = getChildNode(root, DIMENSION);
+        IIOMetadataNode child;
+
+        child = getChildNode(dim, HORIZONTAL_PIXEL_SIZE);
+        if (child == null) {
+            child = new IIOMetadataNode(HORIZONTAL_PIXEL_SIZE);
+            dim.appendChild(child);
+        }
+        child.setAttribute("value", Double.toString(horzValue));
+
+        child = getChildNode(dim, VERTICAL_PIXEL_SIZE);
+        if (child == null) {
+            child = new IIOMetadataNode(VERTICAL_PIXEL_SIZE);
+            dim.appendChild(child);
+        }
+        child.setAttribute("value", Double.toString(vertValue));
+        try {
+            meta.mergeTree(STANDARD_METADATA_FORMAT, root);
+        } catch (IIOInvalidTreeException e) {
+            throw new RuntimeException("Cannot update image metadata: "
+                        + e.getMessage());
+        }
+    }
+
     /**
      * Returns a specific metadata child node
      * @param n the base node
@@ -193,37 +236,31 @@ public class ImageIOImageWriter implemen
         return null;
     }
 
-    /** @see ImageWriter#getMIMEType() */
+    /** {@inheritDoc} */
     public String getMIMEType() {
         return this.targetMIME;
     }
 
-    /** @see org.apache.xmlgraphics.image.writer.ImageWriter#isFunctional() */
+    /** {@inheritDoc} */
     public boolean isFunctional() {
-        Iterator iter = ImageIO.getImageWritersByMIMEType(getMIMEType());
+        Iterator<javax.imageio.ImageWriter> iter = ImageIO.getImageWritersByMIMEType(getMIMEType());
         //Only return true if an IIO ImageWriter is available in the current environment
         return (iter.hasNext());
     }
 
-    /**
-     * @see javax.imageio.event.IIOWriteWarningListener#warningOccurred(
-     *          javax.imageio.ImageWriter, int, java.lang.String)
-     */
+    /** {@inheritDoc} */
     public void warningOccurred(javax.imageio.ImageWriter source,
             int imageIndex, String warning) {
         System.err.println("Problem while writing image using ImageI/O: "
                 + warning);
     }
 
-    /**
-     * @see org.apache.xmlgraphics.image.writer.ImageWriter#createMultiImageWriter(
-     *          java.io.OutputStream)
-     */
+    /** {@inheritDoc} */
     public MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException {
         return new IIOMultiImageWriter(out);
     }
 
-    /** @see org.apache.xmlgraphics.image.writer.ImageWriter#supportsMultiImageWriter() */
+    /** {@inheritDoc} */
     public boolean supportsMultiImageWriter() {
         javax.imageio.ImageWriter iiowriter = getIIOImageWriter();
         try {
@@ -269,7 +306,7 @@ public class ImageIOImageWriter implemen
                     type, iwParam);
             //meta might be null for some JAI codecs as they don't support metadata
             if (params != null && meta != null) {
-                meta = updateMetadata(meta, params);
+                meta = updateMetadata(image, meta, params);
             }
 
             //Write image

Modified: xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWriter.java?rev=1387576&r1=1387575&r2=1387576&view=diff
==============================================================================
--- xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWriter.java (original)
+++ xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOJPEGImageWriter.java Wed Sep 19 13:06:11 2012
@@ -47,17 +47,12 @@ public class ImageIOJPEGImageWriter exte
         super("image/jpeg");
     }
 
-    /**
-     * @see ImageIOImageWriter#updateMetadata(javax.imageio.metadata.IIOMetadata, ImageWriterParams)
-     */
-    protected IIOMetadata updateMetadata(IIOMetadata meta, ImageWriterParams params) {
-        //ImageIODebugUtil.dumpMetadata(meta);
+    @Override
+    protected IIOMetadata updateMetadata(RenderedImage image, IIOMetadata meta,
+            ImageWriterParams params) {
         if (JPEG_NATIVE_FORMAT.equals(meta.getNativeMetadataFormatName())) {
             meta = addAdobeTransform(meta);
-
             IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(JPEG_NATIVE_FORMAT);
-            //IIOMetadataNode root = new IIOMetadataNode(jpegmeta);
-
             IIOMetadataNode jv = getChildNode(root, "JPEGvariety");
             if (jv == null) {
                 jv = new IIOMetadataNode("JPEGvariety");
@@ -75,21 +70,21 @@ public class ImageIOJPEGImageWriter exte
                 //(or not at all) when using standard metadata format.
                 child.setAttribute("majorVersion", null);
                 child.setAttribute("minorVersion", null);
-                child.setAttribute("resUnits", "1"); //dots per inch
-                child.setAttribute("Xdensity", params.getResolution().toString());
-                child.setAttribute("Ydensity", params.getResolution().toString());
+                switch (params.getResolutionUnit()) {
+                case INCH:
+                    child.setAttribute("resUnits", "1"); //dots per inch
+                    break;
+                case CENTIMETER:
+                    child.setAttribute("resUnits", "2"); //dots per cm
+                    break;
+                default:
+                    child.setAttribute("resUnits", "0"); //no unit
+                }
+                child.setAttribute("Xdensity", params.getXResolution().toString());
+                child.setAttribute("Ydensity", params.getYResolution().toString());
                 child.setAttribute("thumbWidth", null);
                 child.setAttribute("thumbHeight", null);
-
             }
-
-            /*
-            IIOMetadataNode ms = getChildNode(root, "markerSequence");
-            if (ms == null) {
-                ms = new IIOMetadataNode("markerSequence");
-                root.appendChild(ms);
-            }*/
-
             try {
                 meta.setFromTree(JPEG_NATIVE_FORMAT, root);
                 //meta.mergeTree(JPEG_NATIVE_FORMAT, root);
@@ -97,13 +92,7 @@ public class ImageIOJPEGImageWriter exte
                 throw new RuntimeException("Cannot update image metadata: "
                             + e.getMessage(), e);
             }
-
-            //ImageIODebugUtil.dumpMetadata(meta);
-
-            //meta = super.updateMetadata(meta, params);
-            //ImageIODebugUtil.dumpMetadata(meta);
         }
-
         return meta;
     }
 
@@ -138,9 +127,8 @@ public class ImageIOJPEGImageWriter exte
         return meta;
     }
 
-    /**
-     * @see ImageIOImageWriter#getDefaultWriteParam(javax.imageio.ImageWriter, java.awt.image.RenderedImage, ImageWriterParams)
-     */
+    /** {@inheritDoc} */
+    @Override
     protected ImageWriteParam getDefaultWriteParam(
             ImageWriter iiowriter, RenderedImage image,
             ImageWriterParams params) {

Modified: xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriter.java?rev=1387576&r1=1387575&r2=1387576&view=diff
==============================================================================
--- xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriter.java (original)
+++ xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/imageio/ImageIOTIFFImageWriter.java Wed Sep 19 13:06:11 2012
@@ -19,11 +19,15 @@
 
 package org.apache.xmlgraphics.image.writer.imageio;
 
+import java.awt.image.RenderedImage;
+
 import javax.imageio.metadata.IIOInvalidTreeException;
 import javax.imageio.metadata.IIOMetadata;
 import javax.imageio.metadata.IIOMetadataNode;
 
+import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder;
 import org.apache.xmlgraphics.image.writer.ImageWriterParams;
+import org.apache.xmlgraphics.image.writer.ResolutionUnit;
 
 // CSOFF: MultipleVariableDeclarations
 
@@ -44,21 +48,17 @@ public class ImageIOTIFFImageWriter exte
         super("image/tiff");
     }
 
-    /**
-     * @see org.apache.xmlgraphics.image.writer.imageio.ImageIOImageWriter#updateMetadata(javax.imageio.metadata.IIOMetadata, org.apache.xmlgraphics.image.writer.ImageWriterParams)
-     */
-    protected IIOMetadata updateMetadata(IIOMetadata meta, ImageWriterParams params) {
-        IIOMetadata ret = super.updateMetadata(meta, params);
-
+    /** {@inheritDoc} */
+    @Override
+    protected IIOMetadata updateMetadata(RenderedImage image, IIOMetadata meta,
+            ImageWriterParams params) {
         //We set the resolution manually using the native format since it appears that
         //it doesn't work properly through the standard metadata. Haven't figured out why
         //that happens.
         if (params.getResolution() != null) {
             if (SUN_TIFF_NATIVE_FORMAT.equals(meta.getNativeMetadataFormatName())) {
-
                 //IIOMetadataNode root = (IIOMetadataNode)meta.getAsTree(SUN_TIFF_NATIVE_FORMAT);
                 IIOMetadataNode root = new IIOMetadataNode(SUN_TIFF_NATIVE_FORMAT);
-
                 IIOMetadataNode ifd = getChildNode(root, "TIFFIFD");
                 if (ifd == null) {
                     ifd = new IIOMetadataNode("TIFFIFD");
@@ -66,21 +66,14 @@ public class ImageIOTIFFImageWriter exte
                                 "com.sun.media.imageio.plugins.tiff.BaselineTIFFTagSet");
                     root.appendChild(ifd);
                 }
-                ifd.appendChild(createResolutionField(282, "XResolution", params));
-                ifd.appendChild(createResolutionField(283, "YResolution", params));
-
-                //ResolutionUnit
-                IIOMetadataNode field, arrayNode, valueNode;
-                field = new IIOMetadataNode("TIFFField");
-                field.setAttribute("number", Integer.toString(296));
-                field.setAttribute("name", "ResolutionUnit");
-                arrayNode = new IIOMetadataNode("TIFFShorts");
-                field.appendChild(arrayNode);
-                valueNode = new IIOMetadataNode("TIFFShort");
-                valueNode.setAttribute("value", Integer.toString(3));
-                valueNode.setAttribute("description", "Centimeter");
-                arrayNode.appendChild(valueNode);
-
+                ifd.appendChild(createResolutionUnitField(params));
+                ifd.appendChild(createResolutionField(TIFFImageDecoder.TIFF_X_RESOLUTION,
+                        "XResolution", params.getXResolution(), params.getResolutionUnit()));
+                ifd.appendChild(createResolutionField(TIFFImageDecoder.TIFF_Y_RESOLUTION,
+                        "YResolution", params.getYResolution(), params.getResolutionUnit()));
+                int rows = params.isSingleStrip() ? image.getHeight() : params.getRowsPerStrip();
+                ifd.appendChild(createShortMetadataNode(TIFFImageDecoder.TIFF_ROWS_PER_STRIP,
+                        "RowsPerStrip", Integer.toString(rows)));
                 try {
                     meta.mergeTree(SUN_TIFF_NATIVE_FORMAT, root);
                 } catch (IIOInvalidTreeException e) {
@@ -89,27 +82,119 @@ public class ImageIOTIFFImageWriter exte
                 }
             }
         }
+        return super.updateMetadata(image, meta, params);
+    }
+
+    //number of pixels in 100 Meters
+    private static final String DENOMINATOR_CENTIMETER = "/" + (100 * 100);
+    private static final String DENOMINATOR_INCH = "/" + 1;
+
+    private IIOMetadataNode createResolutionField(int number, String name,
+            Integer resolution, ResolutionUnit unit) {
+
+        String value;
+
+        if (unit == ResolutionUnit.INCH) {
 
-        return ret;
+            value = resolution + DENOMINATOR_INCH;
+
+        } else {
+
+            float pixSzMM = 25.4f / resolution.floatValue();
+            int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5);
+            value = numPix + DENOMINATOR_CENTIMETER;
+
+        }
+
+        return createRationalMetadataNode(number, name, value);
     }
 
-    private IIOMetadataNode createResolutionField(int number, String name, ImageWriterParams params) {
-        IIOMetadataNode field, arrayNode, valueNode;
-        field = new IIOMetadataNode("TIFFField");
-        field.setAttribute("number", Integer.toString(number));
-        field.setAttribute("name", name);
+    /**
+     * Generate a TIFFField for resolution unit based on the parameters.
+     * @param params
+     * @return the new metadata node
+     */
+    private IIOMetadataNode createResolutionUnitField(ImageWriterParams params) {
+        return createShortMetadataNode(TIFFImageDecoder.TIFF_RESOLUTION_UNIT, "ResolutionUnit",
+                Integer.toString(params.getResolutionUnit().getValue()),
+                params.getResolutionUnit().getDescription());
+    }
+
+    /**
+     * Utility to create a TIFFShort metadata child node of a TIFFShorts node for TIFF metadata.
+     *
+     * @param number value of the number attribute of the TIFField
+     * @param name value of the name attribute of the TIFFField
+     * @param value value of the value attribute of the TIFFShort
+     * @return the new metadata node
+     */
+    public static final IIOMetadataNode createShortMetadataNode(int number,
+            String name, String value) {
+
+        return createShortMetadataNode(number, name, value, null);
+    }
+
+    /**
+     * Utility to create a TIFFShort metadata child node of a TIFFShorts node for TIFF metadata.
+     *
+     * @param number value of the number attribute of the TIFField
+     * @param name value of the name attribute of the TIFFField
+     * @param value value of the value attribute of the TIFFShort
+     * @param description value of the description attribute of the TIFFShort, ignored if null
+     * @return the new metadata node
+     */
+    public static final IIOMetadataNode createShortMetadataNode(int number, String name,
+            String value, String description) {
+
+        IIOMetadataNode field = createMetadataField(number, name);
+        IIOMetadataNode arrayNode, valueNode;
+        arrayNode = new IIOMetadataNode("TIFFShorts");
+        field.appendChild(arrayNode);
+        valueNode = new IIOMetadataNode("TIFFShort");
+        valueNode.setAttribute("value", value);
+        if (description != null) {
+            valueNode.setAttribute("description", description);
+        }
+        arrayNode.appendChild(valueNode);
+
+        return field;
+    }
+
+    /**
+     * Utility to create a TIFFRational metadata child node of a TIFFRationals node for
+     * TIFF metadata.
+     *
+     * @param number value of the number attribute of the TIFField
+     * @param name value of the name attribute of the TIFFField
+     * @param value value of the value attribute of the TIFFRational
+     * @return the new metadata node
+     */
+    public static final IIOMetadataNode createRationalMetadataNode(int number,
+            String name, String value) {
+
+        IIOMetadataNode field = createMetadataField(number, name);
+        IIOMetadataNode arrayNode, valueNode;
         arrayNode = new IIOMetadataNode("TIFFRationals");
         field.appendChild(arrayNode);
         valueNode = new IIOMetadataNode("TIFFRational");
+        valueNode.setAttribute("value", value);
         arrayNode.appendChild(valueNode);
 
-        // Set target resolution
-        float pixSzMM = 25.4f / params.getResolution().floatValue();
-        // num Pixs in 100 Meters
-        int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5);
-        int denom = 100 * 100;  // Centimeters per 100 Meters;
-        valueNode.setAttribute("value", numPix + "/" + denom);
         return field;
     }
 
+    /**
+     * Utility function to create a base TIFFField node for TIFF metadata.
+     *
+     * @param number value of the number attribute of the TIFField
+     * @param name value of the name attribute of the TIFFField
+     * @return the new metadata node
+     */
+    public static final IIOMetadataNode createMetadataField(int number, String name) {
+
+        IIOMetadataNode field = new IIOMetadataNode("TIFFField");
+        field.setAttribute("number", Integer.toString(number));
+        field.setAttribute("name", name);
+        return field;
+    }
 }

Modified: xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.java?rev=1387576&r1=1387575&r2=1387576&view=diff
==============================================================================
--- xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.java (original)
+++ xmlgraphics/commons/branches/Temp_URI_Resolution/src/java/org/apache/xmlgraphics/image/writer/internal/TIFFImageWriter.java Wed Sep 19 13:06:11 2012
@@ -30,6 +30,7 @@ import org.apache.xmlgraphics.image.code
 import org.apache.xmlgraphics.image.writer.AbstractImageWriter;
 import org.apache.xmlgraphics.image.writer.ImageWriterParams;
 import org.apache.xmlgraphics.image.writer.MultiImageWriter;
+import org.apache.xmlgraphics.image.writer.ResolutionUnit;
 
 /**
  * ImageWriter implementation that uses the internal TIFF codec to
@@ -73,22 +74,36 @@ public class TIFFImageWriter extends Abs
             }
 
             if (params.getResolution() != null) {
-                // Set target resolution
-                float pixSzMM = 25.4f / params.getResolution().floatValue();
-                // num Pixs in 100 Meters
-                int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5);
-                int denom = 100 * 100;  // Centimeters per 100 Meters;
-                long [] rational = {numPix, denom};
+                int numPixX;
+                int numPixY;
+                int denom;
+
+                if (ResolutionUnit.INCH == params.getResolutionUnit()) {
+                    numPixX = params.getXResolution().intValue();
+                    numPixY = params.getYResolution().intValue();
+                    denom = 1;
+                } else {
+                    // Set target resolution
+                    float pixXSzMM = 25.4f / params.getXResolution().floatValue();
+                    float pixYSzMM = 25.4f / params.getYResolution().floatValue();
+                    // num Pixs in 100 Meters
+                    numPixX = (int)(((1000 * 100) / pixXSzMM) + 0.5);
+                    numPixY = (int)(((1000 * 100) / pixYSzMM) + 0.5);
+                    denom = 100 * 100;  // Centimeters per 100 Meters;
+                }
+
+                long [] xRational = {numPixX, denom};
+                long [] yRational = {numPixY, denom};
                 TIFFField [] fields = {
                     new TIFFField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT,
                                   TIFFField.TIFF_SHORT, 1,
-                                  new char[] {(char)3}),
+                                  new char[] {(char)params.getResolutionUnit().getValue()}),
                     new TIFFField(TIFFImageDecoder.TIFF_X_RESOLUTION,
                                   TIFFField.TIFF_RATIONAL, 1,
-                                  new long[][] {rational}),
+                                  new long[][] {xRational}),
                     new TIFFField(TIFFImageDecoder.TIFF_Y_RESOLUTION,
                                   TIFFField.TIFF_RATIONAL, 1,
-                                  new long[][] {rational})
+                                  new long[][] {yRational})
                         };
                 encodeParams.setExtraFields(fields);
             }
@@ -102,11 +117,13 @@ public class TIFFImageWriter extends Abs
     }
 
     /** {@inheritDoc} */
+    @Override
     public MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException {
         return new TIFFMultiImageWriter(out);
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean supportsMultiImageWriter() {
         return true;
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org