/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.jpeg; import java.io.IOException; import java.util.List; import java.util.Locale; import javax.imageio.IIOException; import javax.imageio.ImageReader; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.stream.ImageInputStream; import com.sun.media.imageioimpl.common.ImageUtil; public class NativeJPEGImageReaderSpi extends ImageReaderSpi { static final String[] NAMES = { "jpeg", "JPEG", "jpg", "JPG", "jfif", "JFIF", "jpeg-lossless", "JPEG-LOSSLESS" }; static final String[] SUFFIXES = { "jpeg", "jpg", "jfif" }; static final String[] MIMES = { "image/jpeg" }; private boolean registered = false; public NativeJPEGImageReaderSpi() { super("Weasis Team", "1.0", NAMES, SUFFIXES, MIMES, NativeJPEGImageReader.class.getName(), new Class[] { ImageInputStream.class }, new String[] { NativeJPEGImageWriterSpi.class.getName() }, false, // supportsStandardStreamMetadataFormat null, // nativeStreamMetadataFormatName null, // nativeStreamMetadataFormatClassName null, // extraStreamMetadataFormatNames null, // extraStreamMetadataFormatClassNames false, // supportsStandardImageMetadataFormat null, null, null, null); } @Override public void onRegistration(ServiceRegistry registry, Class category) { if (registered) { return; } registered = true; List list = ImageUtil.getJDKImageReaderWriterSPI(registry, "JPEG", true); for (int i = 0; i < list.size(); i++) { // Set this codec to lowest priority registry.setOrdering(category, list.get(i), this); } } @Override public String getDescription(Locale locale) { return "Natively-accelerated JPEG Image Reader (8/12/16 bits, IJG 6b based)"; } @Override public boolean canDecodeInput(Object source) throws IOException { if (!(source instanceof ImageInputStream)) { return false; } ImageInputStream iis = (ImageInputStream) source; iis.mark(); try { int byte1 = iis.read(); int byte2 = iis.read(); // Magic numbers for JPEG (general jpeg marker) if ((byte1 != 0xFF) || (byte2 != 0xD8)) { return false; } do { byte1 = iis.read(); byte2 = iis.read(); // Something wrong, but try to read it anyway if (byte1 != 0xFF) { break; } // Start of scan if (byte2 == 0xDA) { break; } // Start of Frame, also known as SOF55, indicates a JPEG-LS file. Not supported in this reader if (byte2 == 0xF7) { return false; } // 0xffc0: // SOF_0: JPEG baseline // 0xffc1: // SOF_1: JPEG extended sequential DCT // 0xffc2: // SOF_2: JPEG progressive DCT // 0xffc3: // SOF_3: JPEG lossless sequential if ((byte2 >= 0xC0) && (byte2 <= 0xC3)) { return true; } // 0xffc5: // SOF_5: differential (hierarchical) extended sequential, Huffman // 0xffc6: // SOF_6: differential (hierarchical) progressive, Huffman // 0xffc7: // SOF_7: differential (hierarchical) lossless, Huffman if ((byte2 >= 0xC5) && (byte2 <= 0xC7)) { return true; } // 0xffc9: // SOF_9: extended sequential, arithmetic // 0xffca: // SOF_10: progressive, arithmetic // 0xffcb: // SOF_11: lossless, arithmetic if ((byte2 >= 0xC9) && (byte2 <= 0xCB)) { return true; } // 0xffcd: // SOF_13: differential (hierarchical) extended sequential, arithmetic // 0xffce: // SOF_14: differential (hierarchical) progressive, arithmetic // 0xffcf: // SOF_15: differential (hierarchical) lossless, arithmetic if ((byte2 >= 0xCD) && (byte2 <= 0xCF)) { return true; } int length = iis.read() << 8; length += iis.read(); length -= 2; while (length > 0) { length -= iis.skipBytes(length); } } while (true); return true; } finally { iis.reset(); } } @Override public ImageReader createReaderInstance(Object extension) throws IIOException { return new NativeJPEGImageReader(this); } }