View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.imaging.formats.jpeg.iptc;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.io.ByteArrayOutputStream;
25  import java.io.File;
26  import java.io.IOException;
27  import java.util.ArrayList;
28  import java.util.List;
29  import java.util.stream.Stream;
30  
31  import org.apache.commons.imaging.ImagingException;
32  import org.apache.commons.imaging.bytesource.ByteSource;
33  import org.apache.commons.imaging.formats.jpeg.JpegImageParser;
34  import org.apache.commons.imaging.formats.jpeg.JpegImagingParameters;
35  import org.apache.commons.imaging.formats.jpeg.JpegPhotoshopMetadata;
36  import org.junit.jupiter.params.ParameterizedTest;
37  import org.junit.jupiter.params.provider.MethodSource;
38  
39  public class IptcUpdateTest extends IptcBaseTest {
40  
41      public static Stream<File> data() throws Exception {
42          return getImagesWithIptcData().stream();
43      }
44  
45      public byte[] removeIptc(final ByteSource byteSource, final File imageFile) throws Exception {
46          try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
47              new JpegIptcRewriter().removeIptc(byteSource, os);
48              return os.toByteArray();
49          }
50      }
51  
52      @ParameterizedTest
53      @MethodSource("data")
54      public void testInsert(final File imageFile) throws Exception {
55          final ByteSource byteSource = ByteSource.file(imageFile);
56  
57          final JpegImagingParameters params = new JpegImagingParameters();
58  
59          final JpegPhotoshopMetadata metadata = new JpegImageParser().getPhotoshopMetadata(byteSource, params);
60          assertNotNull(metadata);
61  
62          final byte[] noIptcFile = removeIptc(byteSource, imageFile);
63  
64          final List<IptcBlock> newBlocks = new ArrayList<>();
65          final List<IptcRecord> newRecords = new ArrayList<>();
66  
67          newRecords.add(new IptcRecord(IptcTypes.CITY, "Albany, NY"));
68          newRecords.add(new IptcRecord(IptcTypes.CREDIT, "William Sorensen"));
69  
70          final PhotoshopApp13Data newData = new PhotoshopApp13Data(newRecords, newBlocks);
71  
72          byte[] updated;
73          try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
74              new JpegIptcRewriter().writeIptc(ByteSource.array(noIptcFile, "test.jpg"), os, newData);
75              updated = os.toByteArray();
76          }
77  
78          final ByteSource updateByteSource = ByteSource.array(updated, "test.jpg");
79          final JpegPhotoshopMetadata outMetadata = new JpegImageParser().getPhotoshopMetadata(updateByteSource, params);
80  
81          assertNotNull(outMetadata);
82          assertEquals(2, outMetadata.getItems().size());
83      }
84  
85      @ParameterizedTest
86      @MethodSource("data")
87      public void testNoChangeUpdate(final File imageFile) throws Exception {
88          final ByteSource byteSource = ByteSource.file(imageFile);
89  
90          final JpegImagingParameters params = new JpegImagingParameters();
91  
92          final JpegPhotoshopMetadata metadata = new JpegImageParser().getPhotoshopMetadata(byteSource, params);
93          assertNotNull(metadata);
94  
95          final List<IptcBlock> newBlocks = metadata.photoshopApp13Data.getNonIptcBlocks();
96          final List<IptcRecord> oldRecords = metadata.photoshopApp13Data.getRecords();
97          final List<IptcRecord> newRecords = new ArrayList<>();
98          for (final IptcRecord record : oldRecords) {
99              if (record.iptcType != IptcTypes.CITY && record.iptcType != IptcTypes.CREDIT) {
100                 newRecords.add(record);
101             }
102         }
103 
104         newRecords.add(new IptcRecord(IptcTypes.CITY, "Albany, NY"));
105         newRecords.add(new IptcRecord(IptcTypes.CREDIT, "William Sorensen"));
106 
107         final PhotoshopApp13Data newData = new PhotoshopApp13Data(newRecords, newBlocks);
108 
109         final byte[] updated = writeIptc(byteSource, newData, imageFile);
110 
111         final ByteSource updateByteSource = ByteSource.array(updated, "test.jpg");
112         final JpegPhotoshopMetadata outMetadata = new JpegImageParser().getPhotoshopMetadata(updateByteSource, params);
113 
114         assertNotNull(outMetadata);
115         assertEquals(outMetadata.getItems().size(), newRecords.size());
116     }
117 
118     /*
119      * Remove all Photoshop IPTC data from a JPEG file.
120      */
121     @ParameterizedTest
122     @MethodSource("data")
123     public void testRemove(final File imageFile) throws Exception {
124         final ByteSource byteSource = ByteSource.file(imageFile);
125 
126         final JpegImagingParameters params = new JpegImagingParameters();
127 
128         final JpegPhotoshopMetadata metadata = new JpegImageParser().getPhotoshopMetadata(byteSource, params);
129         assertNotNull(metadata);
130 
131         final byte[] noIptcFile = removeIptc(byteSource, imageFile);
132 
133         final JpegPhotoshopMetadata outMetadata = new JpegImageParser().getPhotoshopMetadata(ByteSource.array(noIptcFile, "test.jpg"), params);
134 
135         // FIXME should either be null or empty
136         assertTrue(outMetadata == null || outMetadata.getItems().isEmpty());
137     }
138 
139     @ParameterizedTest
140     @MethodSource("data")
141     public void testUpdate(final File imageFile) throws Exception {
142         final ByteSource byteSource = ByteSource.file(imageFile);
143 
144         final JpegImagingParameters params = new JpegImagingParameters();
145 
146         final JpegPhotoshopMetadata metadata = new JpegImageParser().getPhotoshopMetadata(byteSource, params);
147         assertNotNull(metadata);
148 
149         final List<IptcBlock> newBlocks = metadata.photoshopApp13Data.getNonIptcBlocks();
150         final List<IptcRecord> newRecords = new ArrayList<>();
151 
152         newRecords.add(new IptcRecord(IptcTypes.CITY, "Albany, NY"));
153         newRecords.add(new IptcRecord(IptcTypes.CREDIT, "William Sorensen"));
154 
155         final PhotoshopApp13Data newData = new PhotoshopApp13Data(newRecords, newBlocks);
156 
157         final byte[] updated = writeIptc(byteSource, newData, imageFile);
158 
159         final ByteSource updateByteSource = ByteSource.array(updated, "test.jpg");
160         final JpegPhotoshopMetadata outMetadata = new JpegImageParser().getPhotoshopMetadata(updateByteSource, params);
161 
162         assertNotNull(outMetadata);
163         assertEquals(2, outMetadata.getItems().size());
164     }
165 
166     public byte[] writeIptc(final ByteSource byteSource, final PhotoshopApp13Data newData, final File imageFile)
167             throws IOException, ImagingException, ImagingException {
168         try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
169             new JpegIptcRewriter().writeIptc(byteSource, os, newData);
170             return os.toByteArray();
171         }
172     }
173 
174 }