You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2015/06/10 07:30:34 UTC

svn commit: r1684562 - in /commons/proper/imaging/trunk/src: changes/changes.xml main/java/org/apache/commons/imaging/formats/jpeg/iptc/JpegIptcRewriter.java test/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcFullDiscardTest.java

Author: britter
Date: Wed Jun 10 05:30:34 2015
New Revision: 1684562

URL: http://svn.apache.org/r1684562
Log:
IMAGING-112: JpegIptcRewriter.removeIPTC() does not remove all metadata. Thanks to Xavier Dury.

Added:
    commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcFullDiscardTest.java
Modified:
    commons/proper/imaging/trunk/src/changes/changes.xml
    commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/JpegIptcRewriter.java

Modified: commons/proper/imaging/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/changes/changes.xml?rev=1684562&r1=1684561&r2=1684562&view=diff
==============================================================================
--- commons/proper/imaging/trunk/src/changes/changes.xml (original)
+++ commons/proper/imaging/trunk/src/changes/changes.xml Wed Jun 10 05:30:34 2015
@@ -46,6 +46,9 @@ The <action> type attribute can be add,u
   <body>
 
     <release version="1.0" date="TBA" description="TBA">
+      <action issue="IMAGING-112" dev="britter" type="update" due-to="Xavier Dury">
+        JpegIptcRewriter.removeIPTC() does not remove all metadata
+      </action>
       <action issue="IMAGING-171" dev="britter" type="fix" due-to="Jan Helbich">
         MicrosoftTagTest rewrite image exif fails in some environments
       </action>

Modified: commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/JpegIptcRewriter.java
URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/JpegIptcRewriter.java?rev=1684562&r1=1684561&r2=1684562&view=diff
==============================================================================
--- commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/JpegIptcRewriter.java (original)
+++ commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/JpegIptcRewriter.java Wed Jun 10 05:30:34 2015
@@ -56,8 +56,29 @@ public class JpegIptcRewriter extends Jp
      */
     public void removeIPTC(final File src, final OutputStream os)
             throws ImageReadException, IOException, ImageWriteException {
+        removeIPTC(src, os, false);
+    }
+    
+    /**
+     * Reads a Jpeg image, removes all IPTC data from the App13 segment but
+     * leaves the other data in that segment (if present) unchanged (unless
+     * removeSegment is true) and writes the result to a stream.
+     * <p>
+     * 
+     * @param src
+     *            Image file.
+     * @param os
+     *            OutputStream to write the image to.
+     * @param removeSegment
+     *            Remove the App13 segment.
+     * 
+     * @see java.io.File
+     * @see java.io.OutputStream
+     */
+    public void removeIPTC(final File src, final OutputStream os, final boolean removeSegment)
+            throws ImageReadException, IOException, ImageWriteException {
         final ByteSource byteSource = new ByteSourceFile(src);
-        removeIPTC(byteSource, os);
+        removeIPTC(byteSource, os, removeSegment);
     }
 
     /**
@@ -73,8 +94,26 @@ public class JpegIptcRewriter extends Jp
      */
     public void removeIPTC(final byte[] src, final OutputStream os)
             throws ImageReadException, IOException, ImageWriteException {
+        removeIPTC(src, os, false);
+    }
+    
+    /**
+     * Reads a Jpeg image, removes all IPTC data from the App13 segment but
+     * leaves the other data in that segment (if present) unchanged (unless
+     * removeSegment is true) and writes the result to a stream.
+     * <p>
+     * 
+     * @param src
+     *            Byte array containing Jpeg image data.
+     * @param os
+     *            OutputStream to write the image to.
+     * @param removeSegment
+     *            Remove the App13 segment.
+     */
+    public void removeIPTC(final byte[] src, final OutputStream os, final boolean removeSegment)
+            throws ImageReadException, IOException, ImageWriteException {
         final ByteSource byteSource = new ByteSourceArray(src);
-        removeIPTC(byteSource, os);
+        removeIPTC(byteSource, os, removeSegment);
     }
 
     /**
@@ -90,8 +129,26 @@ public class JpegIptcRewriter extends Jp
      */
     public void removeIPTC(final InputStream src, final OutputStream os)
             throws ImageReadException, IOException, ImageWriteException {
+        removeIPTC(src, os, false);
+    }
+    
+    /**
+     * Reads a Jpeg image, removes all IPTC data from the App13 segment but
+     * leaves the other data in that segment (if present) unchanged (unless
+     * removeSegment is true) and writes the result to a stream.
+     * <p>
+     * 
+     * @param src
+     *            InputStream containing Jpeg image data.
+     * @param os
+     *            OutputStream to write the image to.
+     * @param removeSegment
+     *            Remove the App13 segment.
+     */
+    public void removeIPTC(final InputStream src, final OutputStream os, final boolean removeSegment)
+            throws ImageReadException, IOException, ImageWriteException {
         final ByteSource byteSource = new ByteSourceInputStream(src, null);
-        removeIPTC(byteSource, os);
+        removeIPTC(byteSource, os, removeSegment);
     }
 
     /**
@@ -107,6 +164,24 @@ public class JpegIptcRewriter extends Jp
      */
     public void removeIPTC(final ByteSource byteSource, final OutputStream os)
             throws ImageReadException, IOException, ImageWriteException {
+        removeIPTC(byteSource, os, false);
+    }
+    
+    /**
+     * Reads a Jpeg image, removes all IPTC data from the App13 segment but
+     * leaves the other data in that segment (if present) unchanged (unless
+     * removeSegment is true) and writes the result to a stream.
+     * <p>
+     * 
+     * @param byteSource
+     *            ByteSource containing Jpeg image data.
+     * @param os
+     *            OutputStream to write the image to.
+     * @param removeSegment
+     *            Remove the App13 segment.
+     */
+    public void removeIPTC(final ByteSource byteSource, final OutputStream os, final boolean removeSegment)
+            throws ImageReadException, IOException, ImageWriteException {
         final JFIFPieces jfifPieces = analyzeJFIF(byteSource);
         final List<JFIFPiece> oldPieces = jfifPieces.pieces;
         final List<JFIFPiece> photoshopApp13Segments = findPhotoshopApp13Segments(oldPieces);
@@ -116,7 +191,7 @@ public class JpegIptcRewriter extends Jp
                     "Image contains more than one Photoshop App13 segment.");
         }
         final List<JFIFPiece> newPieces = removePhotoshopApp13Segments(oldPieces);
-        if (photoshopApp13Segments.size() == 1) {
+        if (!removeSegment && photoshopApp13Segments.size() == 1) {
             final JFIFPieceSegment oldSegment = (JFIFPieceSegment) photoshopApp13Segments
                     .get(0);
             final Map<String, Object> params = new HashMap<String, Object>();

Added: commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcFullDiscardTest.java
URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcFullDiscardTest.java?rev=1684562&view=auto
==============================================================================
--- commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcFullDiscardTest.java (added)
+++ commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcFullDiscardTest.java Wed Jun 10 05:30:34 2015
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.imaging.formats.jpeg.iptc;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.util.Collections;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class IptcFullDiscardTest {
+    
+    private byte[] addMetaData(byte[] bytes) throws Exception {
+        IptcRecord record = new IptcRecord(IptcTypes.KEYWORDS, "meta; data");
+        PhotoshopApp13Data data = new PhotoshopApp13Data(Collections.singletonList(record), Collections.<IptcBlock> emptyList());
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        new JpegIptcRewriter().writeIPTC(bytes, byteArrayOutputStream, data);
+        return byteArrayOutputStream.toByteArray();
+    }
+    
+    private byte[] generateImage() throws Exception {
+        BufferedImage image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D graphics2D = image.createGraphics();
+        graphics2D.drawString("Hello World!", 10, 10);
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        ImageIO.write(image, "jpg", byteArrayOutputStream);
+        return byteArrayOutputStream.toByteArray();
+    }
+    
+    private byte[] removeMetaData(byte[] bytes, boolean removeApp13Segment) throws Exception {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        new JpegIptcRewriter().removeIPTC(bytes, byteArrayOutputStream, removeApp13Segment);
+        return byteArrayOutputStream.toByteArray();
+    }
+
+    @Test
+    public void leaveApp13Segment() throws Exception {
+        byte[] originalImage = generateImage();
+        byte[] taggedImage = addMetaData(originalImage);
+        byte[] untaggedImage = removeMetaData(taggedImage, false);
+        Assert.assertEquals(18, untaggedImage.length - originalImage.length);
+    }
+    
+    @Test
+    public void removeApp13Segment() throws Exception {
+        byte[] originalImage = generateImage();
+        byte[] taggedImage = addMetaData(originalImage);
+        byte[] untaggedImage = removeMetaData(taggedImage, true);
+        Assert.assertEquals(originalImage.length, untaggedImage.length);
+    }
+}