diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderSpi.java
index e711d755..d3814c0c 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderSpi.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReaderSpi.java
@@ -64,9 +64,9 @@ public class JPEGImageReaderSpi extends ImageReaderSpi {
new String[]{"JPEG", "jpeg", "JPG", "jpg"},
new String[]{"jpg", "jpeg"},
new String[]{"image/jpeg"},
- JPEGImageReader.class.getName(),
+ "com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader",
STANDARD_INPUT_TYPE,
- null,
+ new String[] {"com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriterSpi"},
true, null, null, null, null,
true, null, null, null, null
);
@@ -135,12 +135,6 @@ public class JPEGImageReaderSpi extends ImageReaderSpi {
return delegateProvider.canDecodeInput(source);
}
- @Override
- public String[] getImageWriterSpiNames() {
- // TODO: The WriterSpi will have a similar method, and it should return the name of this class...
- return delegateProvider.getImageWriterSpiNames();
- }
-
@Override
public String[] getFormatNames() {
return delegateProvider.getFormatNames();
@@ -156,11 +150,6 @@ public class JPEGImageReaderSpi extends ImageReaderSpi {
return delegateProvider.getMIMETypes();
}
- @Override
- public String getPluginClassName() {
- return "com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader";
- }
-
@Override
public boolean isStandardStreamMetadataFormatSupported() {
return delegateProvider.isStandardStreamMetadataFormatSupported();
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriter.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriter.java
new file mode 100644
index 00000000..65363996
--- /dev/null
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriter.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2012, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.plugins.jpeg;
+
+import com.twelvemonkeys.imageio.ImageWriterBase;
+import com.twelvemonkeys.imageio.util.ProgressListenerBase;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteWarningListener;
+import javax.imageio.metadata.IIOMetadata;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * JPEGImageWriter
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: haraldk$
+ * @version $Id: JPEGImageWriter.java,v 1.0 06.02.12 16:39 haraldk Exp$
+ */
+public class JPEGImageWriter extends ImageWriterBase {
+ // TODO: Extend with functionality to be able to write CMYK JPEGs as well?
+
+ /** Our JPEG writing delegate */
+ private final ImageWriter delegate;
+
+ /** Listens to progress updates in the delegate, and delegates back to this instance */
+ private final ProgressDelegator progressDelegator;
+
+ public JPEGImageWriter(final JPEGImageWriterSpi provider, final ImageWriter delegate) {
+ super(provider);
+ this.delegate = delegate;
+
+ progressDelegator = new ProgressDelegator();
+ }
+
+ private void installListeners() {
+ delegate.addIIOWriteProgressListener(progressDelegator);
+ delegate.addIIOWriteWarningListener(progressDelegator);
+ }
+
+ @Override
+ protected void resetMembers() {
+ installListeners();
+ }
+
+ @Override
+ public void setOutput(Object output) {
+ super.setOutput(output);
+
+ delegate.setOutput(output);
+ }
+
+ @Override
+ public Object getOutput() {
+ return delegate.getOutput();
+ }
+
+ @Override
+ public Locale[] getAvailableLocales() {
+ return delegate.getAvailableLocales();
+ }
+
+ @Override
+ public void setLocale(Locale locale) {
+ delegate.setLocale(locale);
+ }
+
+ @Override
+ public Locale getLocale() {
+ return delegate.getLocale();
+ }
+
+ @Override
+ public ImageWriteParam getDefaultWriteParam() {
+ return delegate.getDefaultWriteParam();
+ }
+
+ @Override
+ public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
+ return delegate.getDefaultStreamMetadata(param);
+ }
+
+ @Override
+ public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType, ImageWriteParam param) {
+ return delegate.getDefaultImageMetadata(imageType, param);
+ }
+
+ @Override
+ public IIOMetadata convertStreamMetadata(IIOMetadata inData, ImageWriteParam param) {
+ return delegate.convertStreamMetadata(inData, param);
+ }
+
+ @Override
+ public IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param) {
+ return delegate.convertImageMetadata(inData, imageType, param);
+ }
+
+ @Override
+ public int getNumThumbnailsSupported(ImageTypeSpecifier imageType, ImageWriteParam param, IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
+ return delegate.getNumThumbnailsSupported(imageType, param, streamMetadata, imageMetadata);
+ }
+
+ @Override
+ public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType, ImageWriteParam param, IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
+ return delegate.getPreferredThumbnailSizes(imageType, param, streamMetadata, imageMetadata);
+ }
+
+ @Override
+ public boolean canWriteRasters() {
+ return delegate.canWriteRasters();
+ }
+
+ @Override
+ public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException {
+ delegate.write(streamMetadata, image, param);
+ }
+
+ @Override
+ public void write(IIOImage image) throws IOException {
+ delegate.write(image);
+ }
+
+ @Override
+ public void write(RenderedImage image) throws IOException {
+ delegate.write(image);
+ }
+
+ @Override
+ public boolean canWriteSequence() {
+ return delegate.canWriteSequence();
+ }
+
+ @Override
+ public void prepareWriteSequence(IIOMetadata streamMetadata) throws IOException {
+ delegate.prepareWriteSequence(streamMetadata);
+ }
+
+ @Override
+ public void writeToSequence(IIOImage image, ImageWriteParam param) throws IOException {
+ delegate.writeToSequence(image, param);
+ }
+
+ @Override
+ public void endWriteSequence() throws IOException {
+ delegate.endWriteSequence();
+ }
+
+ @Override
+ public boolean canReplaceStreamMetadata() throws IOException {
+ return delegate.canReplaceStreamMetadata();
+ }
+
+ @Override
+ public void replaceStreamMetadata(IIOMetadata streamMetadata) throws IOException {
+ delegate.replaceStreamMetadata(streamMetadata);
+ }
+
+ @Override
+ public boolean canReplaceImageMetadata(int imageIndex) throws IOException {
+ return delegate.canReplaceImageMetadata(imageIndex);
+ }
+
+ @Override
+ public void replaceImageMetadata(int imageIndex, IIOMetadata imageMetadata) throws IOException {
+ delegate.replaceImageMetadata(imageIndex, imageMetadata);
+ }
+
+ @Override
+ public boolean canInsertImage(int imageIndex) throws IOException {
+ return delegate.canInsertImage(imageIndex);
+ }
+
+ @Override
+ public void writeInsert(int imageIndex, IIOImage image, ImageWriteParam param) throws IOException {
+ delegate.writeInsert(imageIndex, image, param);
+ }
+
+ @Override
+ public boolean canRemoveImage(int imageIndex) throws IOException {
+ return delegate.canRemoveImage(imageIndex);
+ }
+
+ @Override
+ public void removeImage(int imageIndex) throws IOException {
+ delegate.removeImage(imageIndex);
+ }
+
+ @Override
+ public boolean canWriteEmpty() throws IOException {
+ return delegate.canWriteEmpty();
+ }
+
+ @Override
+ public void prepareWriteEmpty(IIOMetadata streamMetadata, ImageTypeSpecifier imageType, int width, int height, IIOMetadata imageMetadata, List extends BufferedImage> thumbnails, ImageWriteParam param) throws IOException {
+ delegate.prepareWriteEmpty(streamMetadata, imageType, width, height, imageMetadata, thumbnails, param);
+ }
+
+ @Override
+ public void endWriteEmpty() throws IOException {
+ delegate.endWriteEmpty();
+ }
+
+ @Override
+ public boolean canInsertEmpty(int imageIndex) throws IOException {
+ return delegate.canInsertEmpty(imageIndex);
+ }
+
+ @Override
+ public void prepareInsertEmpty(int imageIndex, ImageTypeSpecifier imageType, int width, int height, IIOMetadata imageMetadata, List extends BufferedImage> thumbnails, ImageWriteParam param) throws IOException {
+ delegate.prepareInsertEmpty(imageIndex, imageType, width, height, imageMetadata, thumbnails, param);
+ }
+
+ @Override
+ public void endInsertEmpty() throws IOException {
+ delegate.endInsertEmpty();
+ }
+
+ @Override
+ public boolean canReplacePixels(int imageIndex) throws IOException {
+ return delegate.canReplacePixels(imageIndex);
+ }
+
+ @Override
+ public void prepareReplacePixels(int imageIndex, Rectangle region) throws IOException {
+ delegate.prepareReplacePixels(imageIndex, region);
+ }
+
+ @Override
+ public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
+ delegate.replacePixels(image, param);
+ }
+
+ @Override
+ public void replacePixels(Raster raster, ImageWriteParam param) throws IOException {
+ delegate.replacePixels(raster, param);
+ }
+
+ @Override
+ public void endReplacePixels() throws IOException {
+ delegate.endReplacePixels();
+ }
+
+ @Override
+ public void abort() {
+ super.abort();
+ delegate.abort();
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ delegate.reset();
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ delegate.dispose();
+ }
+
+ private class ProgressDelegator extends ProgressListenerBase implements IIOWriteWarningListener {
+ @Override
+ public void imageComplete(ImageWriter source) {
+ processImageComplete();
+ }
+
+ @Override
+ public void imageProgress(ImageWriter source, float percentageDone) {
+ processImageProgress(percentageDone);
+ }
+
+ @Override
+ public void imageStarted(ImageWriter source, int imageIndex) {
+ processImageStarted(imageIndex);
+ }
+
+ @Override
+ public void thumbnailComplete(ImageWriter source) {
+ processThumbnailComplete();
+ }
+
+ @Override
+ public void thumbnailProgress(ImageWriter source, float percentageDone) {
+ processThumbnailProgress(percentageDone);
+ }
+
+ @Override
+ public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
+ processThumbnailStarted(imageIndex, thumbnailIndex);
+ }
+
+ @Override
+ public void writeAborted(ImageWriter source) {
+ processWriteAborted();
+ }
+
+ public void warningOccurred(ImageWriter source, int imageIndex, String warning) {
+ processWarningOccurred(imageIndex, warning);
+ }
+ }
+}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterSpi.java
new file mode 100644
index 00000000..4201be18
--- /dev/null
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterSpi.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.plugins.jpeg;
+
+import com.twelvemonkeys.imageio.spi.ProviderInfo;
+import com.twelvemonkeys.imageio.util.IIOUtil;
+import com.twelvemonkeys.lang.Validate;
+
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.spi.ServiceRegistry;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.util.Locale;
+
+/**
+ * JPEGImageWriterSpi
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: haraldk$
+ * @version $Id: JPEGImageWriterSpi.java,v 1.0 06.02.12 16:09 haraldk Exp$
+ */
+public class JPEGImageWriterSpi extends ImageWriterSpi {
+ private ImageWriterSpi delegateProvider;
+
+ /**
+ * Constructor for use by {@link javax.imageio.spi.IIORegistry} only.
+ * The instance created will not work without being properly registered.
+ */
+ public JPEGImageWriterSpi() {
+ this(IIOUtil.getProviderInfo(JPEGImageWriterSpi.class));
+ }
+
+ private JPEGImageWriterSpi(final ProviderInfo providerInfo) {
+ super(
+ providerInfo.getVendorName(),
+ providerInfo.getVersion(),
+ new String[]{"JPEG", "jpeg", "JPG", "jpg"},
+ new String[]{"jpg", "jpeg"},
+ new String[]{"image/jpeg"},
+ "twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriter",
+ STANDARD_OUTPUT_TYPE,
+ new String[] {"twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi"},
+ true, null, null, null, null,
+ true, null, null, null, null
+ );
+ }
+
+ /**
+ * Creates a {@code JPEGImageWriterSpi} with the given delegate.
+ *
+ * @param delegateProvider a {@code ImageWriterSpi} that can write JPEG.
+ */
+ protected JPEGImageWriterSpi(final ImageWriterSpi delegateProvider) {
+ this(IIOUtil.getProviderInfo(JPEGImageReaderSpi.class));
+
+ this.delegateProvider = Validate.notNull(delegateProvider);
+ }
+
+ static ImageWriterSpi lookupDelegateProvider(final ServiceRegistry registry) {
+ // Should be safe to lookup now, as the bundled providers are hardcoded usually
+ try {
+ return (ImageWriterSpi) registry.getServiceProviderByClass(Class.forName("com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi"));
+ }
+ catch (ClassNotFoundException ignore) {
+ }
+ catch (SecurityException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ @Override
+ public void onRegistration(final ServiceRegistry registry, final Class> category) {
+ if (delegateProvider == null) {
+ // Install delegate now
+ delegateProvider = lookupDelegateProvider(registry);
+ }
+
+ if (delegateProvider != null) {
+ // Order before com.sun provider, to aid ImageIO in selecting our reader
+ registry.setOrdering((Class) category, this, delegateProvider);
+ }
+ else {
+ // Or, if no delegate is found, silently deregister from the registry
+ IIOUtil.deregisterProvider(registry, this, category);
+ }
+ }
+
+ @Override
+ public String getVendorName() {
+ return String.format("%s/%s", super.getVendorName(), delegateProvider.getVendorName());
+ }
+
+ @Override
+ public String getVersion() {
+ return String.format("%s/%s", super.getVersion(), delegateProvider.getVersion());
+ }
+
+ @Override
+ public ImageWriter createWriterInstance(Object extension) throws IOException {
+ return new JPEGImageWriter(this, delegateProvider.createWriterInstance(extension));
+ }
+
+ @Override
+ public String[] getFormatNames() {
+ return delegateProvider.getFormatNames();
+ }
+
+ @Override
+ public String[] getFileSuffixes() {
+ return delegateProvider.getFileSuffixes();
+ }
+
+ @Override
+ public String[] getMIMETypes() {
+ return delegateProvider.getMIMETypes();
+ }
+
+ @Override
+ public boolean isStandardStreamMetadataFormatSupported() {
+ return delegateProvider.isStandardStreamMetadataFormatSupported();
+ }
+
+ @Override
+ public String getNativeStreamMetadataFormatName() {
+ return delegateProvider.getNativeStreamMetadataFormatName();
+ }
+
+ @Override
+ public String[] getExtraStreamMetadataFormatNames() {
+ return delegateProvider.getExtraStreamMetadataFormatNames();
+ }
+
+ @Override
+ public boolean isStandardImageMetadataFormatSupported() {
+ return delegateProvider.isStandardImageMetadataFormatSupported();
+ }
+
+ @Override
+ public String getNativeImageMetadataFormatName() {
+ return delegateProvider.getNativeImageMetadataFormatName();
+ }
+
+ @Override
+ public String[] getExtraImageMetadataFormatNames() {
+ return delegateProvider.getExtraImageMetadataFormatNames();
+ }
+
+ @Override
+ public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
+ return delegateProvider.getStreamMetadataFormat(formatName);
+ }
+
+ @Override
+ public IIOMetadataFormat getImageMetadataFormat(String formatName) {
+ return delegateProvider.getImageMetadataFormat(formatName);
+ }
+
+ @Override
+ public boolean canEncodeImage(ImageTypeSpecifier type) {
+ return delegateProvider.canEncodeImage(type);
+ }
+
+ @Override
+ public boolean canEncodeImage(RenderedImage im) {
+ return delegateProvider.canEncodeImage(im);
+ }
+
+ @Override
+ public String getDescription(Locale locale) {
+ return delegateProvider.getDescription(locale);
+ }
+
+ @Override
+ public boolean isFormatLossless() {
+ return delegateProvider.isFormatLossless();
+ }
+
+ @Override
+ public Class[] getOutputTypes() {
+ return delegateProvider.getOutputTypes();
+ }
+}
diff --git a/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi b/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi
index 90624014..7ae9b24a 100644
--- a/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi
+++ b/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi
@@ -1 +1 @@
-com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi
\ No newline at end of file
+com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi
diff --git a/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageWriterSpi b/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageWriterSpi
new file mode 100644
index 00000000..b15b4f60
--- /dev/null
+++ b/imageio/imageio-jpeg/src/main/resources/META-INF/services/javax.imageio.spi.ImageWriterSpi
@@ -0,0 +1 @@
+com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriterSpi
diff --git a/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java
new file mode 100644
index 00000000..d409b442
--- /dev/null
+++ b/imageio/imageio-jpeg/src/test/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageWriterTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.plugins.jpeg;
+
+import com.twelvemonkeys.imageio.util.ImageWriterAbstractTestCase;
+
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageWriterSpi;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+
+/**
+ * JPEGImageWriterTest
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: haraldk$
+ * @version $Id: JPEGImageWriterTest.java,v 1.0 06.02.12 17:05 haraldk Exp$
+ */
+public class JPEGImageWriterTest extends ImageWriterAbstractTestCase {
+
+ private static final JPEGImageWriterSpi SPI = new JPEGImageWriterSpi(lookupDelegateProvider());
+
+ private static ImageWriterSpi lookupDelegateProvider() {
+ return JPEGImageWriterSpi.lookupDelegateProvider(IIORegistry.getDefaultInstance());
+ }
+
+ @Override
+ protected ImageWriter createImageWriter() {
+ try {
+ return SPI.createWriterInstance();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ protected RenderedImage getTestData() {
+ return new BufferedImage(320, 200, BufferedImage.TYPE_3BYTE_BGR);
+ }
+}