mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-27 00:00:02 -04:00
JPEG Exif/thumbnail refactoring
This commit is contained in:
+4
-3
@@ -39,6 +39,7 @@ import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* AbstractThumbnailReaderTest
|
||||
@@ -52,9 +53,9 @@ public abstract class AbstractThumbnailReaderTest {
|
||||
IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi());
|
||||
}
|
||||
|
||||
protected abstract ThumbnailReader createReader(
|
||||
ThumbnailReadProgressListener progressListener, int imageIndex, int thumbnailIndex, ImageInputStream stream
|
||||
) throws IOException;
|
||||
protected final JPEGSegmentWarningListener listener = mock(JPEGSegmentWarningListener.class);
|
||||
|
||||
protected abstract ThumbnailReader createReader(ImageInputStream stream) throws IOException;
|
||||
|
||||
protected final ImageInputStream createStream(final String name) throws IOException {
|
||||
URL resource = getClass().getResource(name);
|
||||
|
||||
+14
-40
@@ -35,18 +35,19 @@ import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* EXIFThumbnailReaderTest
|
||||
@@ -57,31 +58,28 @@ import static org.mockito.Mockito.*;
|
||||
*/
|
||||
public class EXIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
|
||||
private final ImageReader thumbnailReader = ImageIO.getImageReadersByFormatName("jpeg").next();
|
||||
|
||||
@Override
|
||||
protected EXIFThumbnailReader createReader(final ThumbnailReadProgressListener progressListener, final int imageIndex, final int thumbnailIndex, final ImageInputStream stream) throws IOException {
|
||||
protected ThumbnailReader createReader(final ImageInputStream stream) throws IOException {
|
||||
List<JPEGSegment> segments = JPEGSegmentUtil.readSegments(stream, JPEG.APP1, "Exif");
|
||||
stream.close();
|
||||
|
||||
assertNotNull(segments);
|
||||
assertFalse(segments.isEmpty());
|
||||
|
||||
TIFFReader reader = new TIFFReader();
|
||||
InputStream data = segments.get(0).data();
|
||||
if (data.read() < 0) {
|
||||
throw new AssertionError("EOF!");
|
||||
}
|
||||
JPEGSegment exifSegment = segments.get(0);
|
||||
InputStream data = exifSegment.segmentData();
|
||||
byte[] exifData = new byte[exifSegment.segmentLength() - 2];
|
||||
new DataInputStream(data).readFully(exifData);
|
||||
|
||||
ImageInputStream exifStream = ImageIO.createImageInputStream(data);
|
||||
CompoundDirectory ifds = (CompoundDirectory) reader.read(exifStream);
|
||||
|
||||
assertEquals(2, ifds.directoryCount());
|
||||
|
||||
return new EXIFThumbnailReader(progressListener, ImageIO.getImageReadersByFormatName("JPEG").next(), imageIndex, thumbnailIndex, ifds.getDirectory(1), exifStream);
|
||||
EXIF exif = new EXIF(exifData);
|
||||
return EXIFThumbnail.from(exif, (CompoundDirectory) new TIFFReader().read(exif.exifData()), thumbnailReader, listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadJPEG() throws IOException {
|
||||
ThumbnailReader reader = createReader(mock(ThumbnailReadProgressListener.class), 0, 0, createStream("/jpeg/cmyk-sample-multiple-chunk-icc.jpg"));
|
||||
ThumbnailReader reader = createReader(createStream("/jpeg/cmyk-sample-multiple-chunk-icc.jpg"));
|
||||
|
||||
assertEquals(114, reader.getWidth());
|
||||
assertEquals(160, reader.getHeight());
|
||||
@@ -94,7 +92,7 @@ public class EXIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
|
||||
@Test
|
||||
public void testReadRaw() throws IOException {
|
||||
ThumbnailReader reader = createReader(mock(ThumbnailReadProgressListener.class), 0, 0, createStream("/jpeg/exif-rgb-thumbnail-sony-d700.jpg"));
|
||||
ThumbnailReader reader = createReader(createStream("/jpeg/exif-rgb-thumbnail-sony-d700.jpg"));
|
||||
|
||||
assertEquals(80, reader.getWidth());
|
||||
assertEquals(60, reader.getHeight());
|
||||
@@ -104,28 +102,4 @@ public class EXIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
assertEquals(80, thumbnail.getWidth());
|
||||
assertEquals(60, thumbnail.getHeight());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressListenerJPEG() throws IOException {
|
||||
ThumbnailReadProgressListener listener = mock(ThumbnailReadProgressListener.class);
|
||||
|
||||
createReader(listener, 42, 43, createStream("/jpeg/cmyk-sample-multiple-chunk-icc.jpg")).read();
|
||||
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).thumbnailStarted(42, 43);
|
||||
order.verify(listener, atLeastOnce()).thumbnailProgress(100f);
|
||||
order.verify(listener).thumbnailComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressListenerRaw() throws IOException {
|
||||
ThumbnailReadProgressListener listener = mock(ThumbnailReadProgressListener.class);
|
||||
|
||||
createReader(listener, 0, 99, createStream("/jpeg/exif-rgb-thumbnail-sony-d700.jpg")).read();
|
||||
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).thumbnailStarted(0, 99);
|
||||
order.verify(listener, atLeastOnce()).thumbnailProgress(100f);
|
||||
order.verify(listener).thumbnailComplete();
|
||||
}
|
||||
}
|
||||
|
||||
+48
-17
@@ -33,8 +33,8 @@ package com.twelvemonkeys.imageio.plugins.jpeg;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -53,8 +53,9 @@ import static org.mockito.Mockito.*;
|
||||
* @version $Id: JFIFThumbnailReaderTest.java,v 1.0 04.05.12 15:56 haraldk Exp$
|
||||
*/
|
||||
public class JFIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
|
||||
@Override
|
||||
protected JFIFThumbnailReader createReader(ThumbnailReadProgressListener progressListener, int imageIndex, int thumbnailIndex, ImageInputStream stream) throws IOException {
|
||||
protected ThumbnailReader createReader(ImageInputStream stream) throws IOException {
|
||||
List<JPEGSegment> segments = JPEGSegmentUtil.readSegments(stream, JPEG.APP0, "JFIF");
|
||||
stream.close();
|
||||
|
||||
@@ -62,12 +63,54 @@ public class JFIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
assertFalse(segments.isEmpty());
|
||||
|
||||
JPEGSegment segment = segments.get(0);
|
||||
return new JFIFThumbnailReader(progressListener, imageIndex, thumbnailIndex, JFIF.read(new DataInputStream(segment.segmentData()), segment.segmentLength()));
|
||||
|
||||
return JFIFThumbnail.from(JFIF.read(new DataInputStream(segment.segmentData()), segment.segmentLength()), listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromNull() {
|
||||
assertNull(JFIFThumbnail.from(null, listener));
|
||||
|
||||
verify(listener, never()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromNullThumbnail() {
|
||||
assertNull(JFIFThumbnail.from(new JFIF(1, 1, 0, 1, 1, 0, 0, null), listener));
|
||||
|
||||
verify(listener, never()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromEmpty() {
|
||||
assertNull(JFIFThumbnail.from(new JFIF(1, 1, 0, 1, 1, 0, 0, new byte[0]), listener));
|
||||
|
||||
verify(listener, never()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromTruncated() {
|
||||
assertNull(JFIFThumbnail.from(new JFIF(1, 1, 0, 1, 1, 255, 170, new byte[99]), listener));
|
||||
|
||||
verify(listener, only()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromValid() throws IOException {
|
||||
ThumbnailReader reader = JFIFThumbnail.from(new JFIF(1, 1, 0, 1, 1, 30, 20, new byte[30 * 20 * 3]), listener);
|
||||
assertNotNull(reader);
|
||||
|
||||
verify(listener, never()).warningOccurred(anyString());
|
||||
|
||||
// Sanity check below
|
||||
assertEquals(30, reader.getWidth());
|
||||
assertEquals(20, reader.getHeight());
|
||||
assertNotNull(reader.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRaw() throws IOException {
|
||||
ThumbnailReader reader = createReader(mock(ThumbnailReadProgressListener.class), 0, 0, createStream("/jpeg/jfif-jfif-and-exif-thumbnail-sharpshot-iphone.jpg"));
|
||||
ThumbnailReader reader = createReader(createStream("/jpeg/jfif-jfif-and-exif-thumbnail-sharpshot-iphone.jpg"));
|
||||
|
||||
assertEquals(131, reader.getWidth());
|
||||
assertEquals(122, reader.getHeight());
|
||||
@@ -80,7 +123,7 @@ public class JFIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
|
||||
@Test
|
||||
public void testReadNonSpecGray() throws IOException {
|
||||
ThumbnailReader reader = createReader(mock(ThumbnailReadProgressListener.class), 0, 0, createStream("/jpeg/jfif-grayscale-thumbnail.jpg"));
|
||||
ThumbnailReader reader = createReader(createStream("/jpeg/jfif-grayscale-thumbnail.jpg"));
|
||||
|
||||
assertEquals(127, reader.getWidth());
|
||||
assertEquals(76, reader.getHeight());
|
||||
@@ -91,16 +134,4 @@ public class JFIFThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
assertEquals(127, thumbnail.getWidth());
|
||||
assertEquals(76, thumbnail.getHeight());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressListenerRaw() throws IOException {
|
||||
ThumbnailReadProgressListener listener = mock(ThumbnailReadProgressListener.class);
|
||||
|
||||
createReader(listener, 0, 99, createStream("/jpeg/jfif-jfif-and-exif-thumbnail-sharpshot-iphone.jpg")).read();
|
||||
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).thumbnailStarted(0, 99);
|
||||
order.verify(listener, atLeastOnce()).thumbnailProgress(100f);
|
||||
order.verify(listener).thumbnailComplete();
|
||||
}
|
||||
}
|
||||
|
||||
+78
-16
@@ -33,10 +33,12 @@ package com.twelvemonkeys.imageio.plugins.jpeg;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.DataInputStream;
|
||||
@@ -44,6 +46,7 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
@@ -54,8 +57,10 @@ import static org.mockito.Mockito.*;
|
||||
* @version $Id: JFXXThumbnailReaderTest.java,v 1.0 04.05.12 15:56 haraldk Exp$
|
||||
*/
|
||||
public class JFXXThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
private final ImageReader thumbnailReader = ImageIO.getImageReadersByFormatName("jpeg").next();
|
||||
|
||||
@Override
|
||||
protected JFXXThumbnailReader createReader(ThumbnailReadProgressListener progressListener, int imageIndex, int thumbnailIndex, ImageInputStream stream) throws IOException {
|
||||
protected ThumbnailReader createReader(ImageInputStream stream) throws IOException {
|
||||
List<JPEGSegment> segments = JPEGSegmentUtil.readSegments(stream, JPEG.APP0, "JFXX");
|
||||
stream.close();
|
||||
|
||||
@@ -63,12 +68,81 @@ public class JFXXThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
assertFalse(segments.isEmpty());
|
||||
|
||||
JPEGSegment jfxx = segments.get(0);
|
||||
return new JFXXThumbnailReader(progressListener, ImageIO.getImageReadersByFormatName("jpeg").next(), imageIndex, thumbnailIndex, JFXX.read(new DataInputStream(jfxx.segmentData()), jfxx.length()));
|
||||
return JFXXThumbnail.from(JFXX.read(new DataInputStream(jfxx.segmentData()), jfxx.length()), thumbnailReader, listener);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
thumbnailReader.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromNull() {
|
||||
assertNull(JFXXThumbnail.from(null, thumbnailReader, listener));
|
||||
|
||||
verify(listener, never()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromNullThumbnail() {
|
||||
assertNull(JFXXThumbnail.from(new JFXX(JFXX.JPEG, null), thumbnailReader, listener));
|
||||
|
||||
verify(listener, only()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromEmpty() {
|
||||
assertNull(JFXXThumbnail.from(new JFXX(JFXX.JPEG, new byte[0]), thumbnailReader, listener));
|
||||
|
||||
verify(listener, only()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromTruncatedJPEG() {
|
||||
assertNull(JFXXThumbnail.from(new JFXX(JFXX.JPEG, new byte[99]), thumbnailReader, listener));
|
||||
|
||||
verify(listener, only()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromTruncatedRGB() {
|
||||
byte[] thumbnail = new byte[765];
|
||||
thumbnail[0] = (byte) 160;
|
||||
thumbnail[1] = 90;
|
||||
assertNull(JFXXThumbnail.from(new JFXX(JFXX.RGB, thumbnail), thumbnailReader, listener));
|
||||
|
||||
verify(listener, only()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromTruncatedIndexed() {
|
||||
byte[] thumbnail = new byte[365];
|
||||
thumbnail[0] = (byte) 160;
|
||||
thumbnail[1] = 90;
|
||||
assertNull(JFXXThumbnail.from(new JFXX(JFXX.INDEXED, thumbnail), thumbnailReader, listener));
|
||||
|
||||
verify(listener, only()).warningOccurred(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromValid() throws IOException {
|
||||
byte[] thumbnail = new byte[14];
|
||||
thumbnail[0] = 2;
|
||||
thumbnail[1] = 2;
|
||||
ThumbnailReader reader = JFXXThumbnail.from(new JFXX(JFXX.RGB, thumbnail), thumbnailReader, listener);
|
||||
assertNotNull(reader);
|
||||
|
||||
verify(listener, never()).warningOccurred(anyString());
|
||||
|
||||
// Sanity check below
|
||||
assertEquals(2, reader.getWidth());
|
||||
assertEquals(2, reader.getHeight());
|
||||
assertNotNull(reader.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadJPEG() throws IOException {
|
||||
ThumbnailReader reader = createReader(mock(ThumbnailReadProgressListener.class), 0, 0, createStream("/jpeg/jfif-jfxx-thumbnail-olympus-d320l.jpg"));
|
||||
ThumbnailReader reader = createReader(createStream("/jpeg/jfif-jfxx-thumbnail-olympus-d320l.jpg"));
|
||||
|
||||
assertEquals(80, reader.getWidth());
|
||||
assertEquals(60, reader.getHeight());
|
||||
@@ -81,16 +155,4 @@ public class JFXXThumbnailReaderTest extends AbstractThumbnailReaderTest {
|
||||
|
||||
// TODO: Test JFXX indexed thumbnail
|
||||
// TODO: Test JFXX RGB thumbnail
|
||||
|
||||
@Test
|
||||
public void testProgressListenerRaw() throws IOException {
|
||||
ThumbnailReadProgressListener listener = mock(ThumbnailReadProgressListener.class);
|
||||
|
||||
createReader(listener, 0, 99, createStream("/jpeg/jfif-jfxx-thumbnail-olympus-d320l.jpg")).read();
|
||||
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).thumbnailStarted(0, 99);
|
||||
order.verify(listener, atLeastOnce()).thumbnailProgress(100f);
|
||||
order.verify(listener).thumbnailComplete();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user