/*******************************************************************************
* 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);
}
}