/*
* ImageI/O-Ext - OpenSource Java Image translation Library
* http://www.geo-solutions.it/
* http://java.net/projects/imageio-ext/
* (C) 2007 - 2009, GeoSolutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* either version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package it.geosolutions.imageio.matfile5;
import it.geosolutions.imageio.stream.input.FileImageInputStreamExtImpl;
import it.geosolutions.imageio.utilities.Utilities;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import com.jmatio.io.MatlabIOException;
/**
* The abstract service provider interface (SPI) for {@link MatFileImageReader}s.
*
* @author Daniele Romagnoli, GeoSolutions.
* @author Simone Giannecchini, GeoSolutions.
*/
public abstract class MatFileImageReaderSpi extends ImageReaderSpi {
static final String[] suffixes = { "mat" };
static final String[] formatNames = { "Mat", "Mat5" }; // TODO: Improve this
static final String[] MIMETypes = { "image/mat" };
static final String version = "1.0";
static final String readerCN = "it.geosolutions.imageio.matfile5.MatFileImageReader";
static final String vendorName = "GeoSolutions";
// writerSpiNames
static final String[] wSN = { null };
// StreamMetadataFormatNames and StreamMetadataFormatClassNames
static final boolean supportsStandardStreamMetadataFormat = false;
static final String nativeStreamMetadataFormatName = null;
static final String nativeStreamMetadataFormatClassName = null;
static final String[] extraStreamMetadataFormatNames = { null };
static final String[] extraStreamMetadataFormatClassNames = { null };
// ImageMetadataFormatNames and ImageMetadataFormatClassNames
static final boolean supportsStandardImageMetadataFormat = false;
static final String nativeImageMetadataFormatName = "";
static final String nativeImageMetadataFormatClassName = "";
static final String[] extraImageMetadataFormatNames = { null };
static final String[] extraImageMetadataFormatClassNames = { null };
private static final String MAT_FILE_5 = "MATLAB 5.0 MAT-file.*";
private static final Logger LOGGER = Logger
.getLogger("it.geosolutions.imageio.matfile5");
public MatFileImageReaderSpi() {
super(
vendorName,
version,
formatNames,
suffixes,
MIMETypes,
readerCN, // readerClassName
new Class[] { File.class, FileImageInputStreamExtImpl.class },
wSN, // writer Spi Names
supportsStandardStreamMetadataFormat,
nativeStreamMetadataFormatName,
nativeStreamMetadataFormatClassName,
extraStreamMetadataFormatNames,
extraStreamMetadataFormatClassNames,
supportsStandardImageMetadataFormat,
nativeImageMetadataFormatName,
nativeImageMetadataFormatClassName,
extraImageMetadataFormatNames,
extraImageMetadataFormatClassNames);
}
public MatFileImageReaderSpi(String vendorName, String version,
String[] formatNames, String[] suffixes, String[] types,
String readerCN, Class<?>[] classes, String[] wsn,
boolean supportsStandardStreamMetadataFormat,
String nativeStreamMetadataFormatName,
String nativeStreamMetadataFormatClassName,
String[] extraStreamMetadataFormatNames,
String[] extraStreamMetadataFormatClassNames,
boolean supportsStandardImageMetadataFormat,
String nativeImageMetadataFormatName,
String nativeImageMetadataFormatClassName,
String[] extraImageMetadataFormatNames,
String[] extraImageMetadataFormatClassNames) {
super(
vendorName,
version,
formatNames,
suffixes,
types,
readerCN, // readerClassName
classes,
wsn, // writer Spi Names
supportsStandardStreamMetadataFormat,
nativeStreamMetadataFormatName,
nativeStreamMetadataFormatClassName,
extraStreamMetadataFormatNames,
extraStreamMetadataFormatClassNames,
supportsStandardImageMetadataFormat,
nativeImageMetadataFormatName,
nativeImageMetadataFormatClassName,
extraImageMetadataFormatNames,
extraImageMetadataFormatClassNames);
}
/**
* Checks if the provided input can be decoded by the specific SPI.
*
* @return
* <code>true</code> if the input can be successfully decoded.
*/
public boolean canDecodeInput(Object input) throws IOException {
if (LOGGER.isLoggable(Level.FINE))
LOGGER.fine("Can Decode Input");
if (input instanceof ImageInputStream)
((ImageInputStream) input).mark();
// if input source is a string,
// convert input from String to File
if (input instanceof String)
input = new File((String) input);
// if input source is an URL, open an InputStream
if (input instanceof URL) {
final URL tempURL = (URL) input;
if (tempURL.getProtocol().equalsIgnoreCase("file"))
input = Utilities.urlToFile(tempURL);
else
input = ((URL) input).openStream();
}
// if input source is a File,
// convert input from File to FileInputStream
if (input instanceof File)
input = new FileImageInputStreamExtImpl((File) input);
boolean isInputDecodable = false;
// Checking if this specific SPI can decode the provided input
try {
final String file = ((FileImageInputStreamExtImpl) input).getFile()
.getAbsolutePath();
isInputDecodable = isDecodable(file);
} catch (Exception e) {
}
return isInputDecodable;
}
protected boolean isDecodable(final String file)
throws IOException {
if (file == null || file.trim().length() < 1)
return false;
RandomAccessFile raFile = new RandomAccessFile(file, "r");
FileChannel roChannel = raFile.getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect(128);
roChannel.read(buf, 0);
buf.rewind();
try {
checkHeader(buf);
} catch (MatlabIOException mlio) {
if (LOGGER.isLoggable(Level.FINE))
LOGGER.fine("This is not a valid MATLAB 5.0 MAT-file.");
return false;
} finally {
if (roChannel != null) {
roChannel.close();
}
if (raFile != null) {
raFile.close();
}
}
return true;
}
private void checkHeader(ByteBuffer buf) throws IOException {
// header values
String description;
// descriptive text 116 bytes
byte[] descriptionBuffer = new byte[116];
buf.get(descriptionBuffer);
description = new String(descriptionBuffer);
if (!description.matches(MAT_FILE_5)) {
throw new MatlabIOException(
"This is not a valid MATLAB 5.0 MAT-file.");
}
}
@Override
public String getDescription(Locale locale) {
return new StringBuffer("MATLAB 5.0 MAT-Files Image Reader, version ")
.append(version).toString();
}
}