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.bytesource;
19  
20  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertNotSame;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.awt.Dimension;
28  import java.awt.image.BufferedImage;
29  import java.io.File;
30  import java.io.IOException;
31  import java.lang.reflect.InvocationTargetException;
32  import java.lang.reflect.Method;
33  import java.lang.reflect.Modifier;
34  import java.util.stream.Stream;
35  
36  import org.apache.commons.imaging.AbstractImageParser;
37  import org.apache.commons.imaging.ImageFormat;
38  import org.apache.commons.imaging.ImageFormats;
39  import org.apache.commons.imaging.ImageInfo;
40  import org.apache.commons.imaging.Imaging;
41  import org.apache.commons.imaging.ImagingException;
42  import org.apache.commons.imaging.ImagingParameters;
43  import org.apache.commons.imaging.formats.jpeg.JpegImagingParameters;
44  import org.apache.commons.imaging.formats.tiff.TiffImagingParameters;
45  import org.apache.commons.imaging.internal.Debug;
46  import org.apache.commons.imaging.internal.ImageParserFactory;
47  import org.apache.commons.io.FileUtils;
48  import org.junit.jupiter.params.ParameterizedTest;
49  import org.junit.jupiter.params.provider.MethodSource;
50  
51  public class ByteSourceImageTest extends AbstractByteSourceTest {
52  
53      public static Stream<File> data() throws Exception {
54          return getTestImages().stream();
55      }
56  
57      public void checkGetBufferedImage(final File file, final byte[] bytes) throws Exception {
58          final BufferedImage bufferedImage = Imaging.getBufferedImage(file);
59          assertNotNull(bufferedImage);
60          assertTrue(bufferedImage.getWidth() > 0);
61          assertTrue(bufferedImage.getHeight() > 0);
62          final int imageFileWidth = bufferedImage.getWidth();
63          final int imageFileHeight = bufferedImage.getHeight();
64  
65          final BufferedImage imageBytes = Imaging.getBufferedImage(bytes);
66          assertNotNull(imageBytes);
67          assertEquals(imageFileWidth, imageBytes.getWidth());
68          assertEquals(imageFileHeight, imageBytes.getHeight());
69      }
70  
71      public void checkGetIccProfileBytes(final File imageFile, final byte[] imageFileBytes) throws Exception {
72          // check guessFormat()
73          final byte[] iccBytesFile = Imaging.getIccProfileBytes(imageFile);
74  
75          final byte[] iccBytesBytes = Imaging.getIccProfileBytes(imageFileBytes);
76  
77          assertEquals(iccBytesFile != null, iccBytesBytes != null);
78  
79          if (iccBytesFile == null) {
80              return;
81          }
82  
83          assertArrayEquals(iccBytesFile, iccBytesBytes);
84      }
85  
86      public void checkGetImageInfo(final File imageFile, final byte[] imageFileBytes)
87              throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ImagingException {
88          final boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
89          final ImageFormat imageFormat = Imaging.guessFormat(imageFile);
90          ImagingParameters params = null;
91          if (imageFormat == ImageFormats.TIFF) {
92              params = new TiffImagingParameters().setReadThumbnails(!ignoreImageData);
93          }
94          if (imageFormat == ImageFormats.JPEG) {
95              params = new JpegImagingParameters();
96          }
97  
98          final AbstractImageParser abstractImageParser = ImageParserFactory.getImageParser(imageFormat);
99  
100         final ImageInfo imageInfoFile = abstractImageParser.getImageInfo(imageFile, params);
101 
102         final ImageInfo imageInfoBytes = abstractImageParser.getImageInfo(imageFileBytes, params);
103 
104         assertNotNull(imageInfoFile);
105         assertNotNull(imageInfoBytes);
106 
107         final Method[] methods = ImageInfo.class.getMethods();
108         for (final Method method2 : methods) {
109             if (!Modifier.isPublic(method2.getModifiers())) {
110                 continue;
111             }
112             if (!method2.getName().startsWith("get")) {
113                 continue;
114             }
115             if (method2.getName().equals("getClass")) {
116                 continue;
117                 // if (method.getGenericParameterTypes().length > 0)
118                 // continue;
119             }
120 
121             final Object valueFile = method2.invoke(imageInfoFile, (Object[]) null);
122             final Object valueBytes = method2.invoke(imageInfoBytes, (Object[]) null);
123 
124             assertEquals(valueFile, valueBytes);
125         }
126 
127         // only have to test values from imageInfoFile; we already know values
128         // match.
129         assertTrue(imageInfoFile.getBitsPerPixel() > 0);
130 
131         assertNotNull(imageInfoFile.getFormat());
132         assertNotSame(imageInfoFile.getFormat(), ImageFormats.UNKNOWN);
133 
134         assertNotNull(imageInfoFile.getFormatName());
135 
136         assertTrue(imageInfoFile.getWidth() > 0);
137         assertTrue(imageInfoFile.getHeight() > 0);
138 
139         assertNotNull(imageInfoFile.getMimeType());
140 
141         // TODO: not all adapters count images yet.
142         // assertTrue(imageInfoFile.getNumberOfImages() > 0);
143 
144     }
145 
146     public void checkGetImageSize(final File imageFile, final byte[] imageFileBytes) throws Exception {
147         final Dimension imageSizeFile = Imaging.getImageSize(imageFile);
148         assertNotNull(imageSizeFile);
149         assertTrue(imageSizeFile.width > 0);
150         assertTrue(imageSizeFile.height > 0);
151 
152         final Dimension imageSizeBytes = Imaging.getImageSize(imageFileBytes);
153         assertNotNull(imageSizeBytes);
154         assertEquals(imageSizeFile.width, imageSizeBytes.width);
155         assertEquals(imageSizeFile.height, imageSizeBytes.height);
156     }
157 
158     public void checkGuessFormat(final File imageFile, final byte[] imageFileBytes) throws Exception {
159         // check guessFormat()
160         final ImageFormat imageFormatFile = Imaging.guessFormat(imageFile);
161         assertNotNull(imageFormatFile);
162         assertNotSame(imageFormatFile, ImageFormats.UNKNOWN);
163         // Debug.debug("imageFormatFile", imageFormatFile);
164 
165         final ImageFormat imageFormatBytes = Imaging.guessFormat(imageFileBytes);
166         assertNotNull(imageFormatBytes);
167         assertNotSame(imageFormatBytes, ImageFormats.UNKNOWN);
168         // Debug.debug("imageFormatBytes", imageFormatBytes);
169 
170         assertSame(imageFormatBytes, imageFormatFile);
171     }
172 
173     @ParameterizedTest
174     @MethodSource("data")
175     public void test(final File imageFile) throws Exception {
176         Debug.debug("imageFile", imageFile);
177         assertNotNull(imageFile);
178 
179         final byte[] imageFileBytes = FileUtils.readFileToByteArray(imageFile);
180         assertNotNull(imageFileBytes);
181         assertEquals(imageFileBytes.length, imageFile.length());
182 
183         if (imageFile.getName().toLowerCase().endsWith(".ico") || imageFile.getName().toLowerCase().endsWith(".tga")
184                 || imageFile.getName().toLowerCase().endsWith(".jb2") || imageFile.getName().toLowerCase().endsWith(".pcx")
185                 || imageFile.getName().toLowerCase().endsWith(".dcx") || imageFile.getName().toLowerCase().endsWith(".psd")
186                 || imageFile.getName().toLowerCase().endsWith(".wbmp") || imageFile.getName().toLowerCase().endsWith(".xbm")
187                 || imageFile.getName().toLowerCase().endsWith(".xpm")) {
188             // these formats can't be parsed without a file name hint.
189             // they have ambiguous "magic number" signatures.
190             return;
191         }
192 
193         checkGuessFormat(imageFile, imageFileBytes);
194 
195         if (imageFile.getName().toLowerCase().endsWith(".png") && imageFile.getParentFile().getName().equalsIgnoreCase("pngsuite")
196                 && imageFile.getName().toLowerCase().startsWith("x")) {
197             return;
198         }
199 
200         checkGetIccProfileBytes(imageFile, imageFileBytes);
201 
202         if (!imageFile.getParentFile().getName().toLowerCase().equals("@broken")) {
203             checkGetImageInfo(imageFile, imageFileBytes);
204         }
205 
206         checkGetImageSize(imageFile, imageFileBytes);
207 
208         final ImageFormat imageFormat = Imaging.guessFormat(imageFile);
209         if (ImageFormats.JPEG != imageFormat && ImageFormats.WEBP != imageFormat && ImageFormats.UNKNOWN != imageFormat) {
210             checkGetBufferedImage(imageFile, imageFileBytes);
211         }
212     }
213 }