/******************************************************************************* * 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.openjpeg; 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 NativeJ2kImageReaderSpi extends ImageReaderSpi { static final String[] SUFFIXES = { "jp2", "jp2k", "j2k", "j2c" }; static final String[] NAMES = { "JP2KSimpleBox", "jpeg2000", "jpeg 2000", "JPEG 2000", "JPEG2000" }; static final String[] MIMES = { "image/jp2", "image/jp2k", "image/j2k", "image/j2c" }; private boolean registered = false; public NativeJ2kImageReaderSpi() { super("Weasis Team", "1.0", NAMES, SUFFIXES, MIMES, NativeJ2kImageReader.class.getName(), new Class[] { ImageInputStream.class }, new String[] { NativeJ2kImageWriterSpi.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 2000", false); for (int i = 0; i < list.size(); i++) { // Set this codec to higher priority registry.setOrdering(category, this, list.get(i)); } } @Override public String getDescription(Locale locale) { return "Natively-accelerated JPEG2000 Image Reader (OpenJPEG based)"; } @Override public boolean canDecodeInput(Object source) throws IOException { if (!(source instanceof ImageInputStream)) { return false; } ImageInputStream iis = (ImageInputStream) source; iis.mark(); try { int marker = (iis.read() << 8) | iis.read(); if (marker == 0xFF4F) { return true; } iis.reset(); iis.mark(); byte[] b = new byte[12]; iis.readFully(b); // Verify the signature box // The length of the signature box is 12 if (b[0] != 0 || b[1] != 0 || b[2] != 0 || b[3] != 12) { return false; } // The signature box type is "jP " if ((b[4] & 0xff) != 0x6A || (b[5] & 0xFF) != 0x50 || (b[6] & 0xFF) != 0x20 || (b[7] & 0xFF) != 0x20) { return false; } // The signature content is 0x0D0A870A if ((b[8] & 0xFF) != 0x0D || (b[9] & 0xFF) != 0x0A || (b[10] & 0xFF) != 0x87 || (b[11] & 0xFF) != 0x0A) { return false; } return true; } finally { iis.reset(); } } @Override public ImageReader createReaderInstance(Object extension) throws IIOException { return new NativeJ2kImageReader(this); } }