/*
* #%L
* OME Bio-Formats package for reading and converting biological file formats.
* %%
* Copyright (C) 2005 - 2015 Open Microscopy Environment:
* - Board of Regents of the University of Wisconsin-Madison
* - Glencoe Software, Inc.
* - University of Dundee
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/
package loci.formats.in;
import java.io.IOException;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Vector;
import loci.common.DataTools;
import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.common.services.ServiceFactory;
import loci.formats.CoreMetadata;
import loci.formats.FormatException;
import loci.formats.FormatReader;
import loci.formats.FormatTools;
import loci.formats.MetadataTools;
import loci.formats.MissingLibraryException;
import loci.formats.meta.MetadataStore;
import loci.formats.services.NetCDFService;
import ome.xml.model.primitives.PositiveFloat;
/**
* VeecoReader is the file format reader for Veeco HDF files.
*/
public class VeecoReader extends FormatReader {
// -- Fields --
private NetCDFService netcdf;
private Object image;
private boolean unpackEndian = true;
// -- Constructor --
/** Constructs a new Veeco reader. */
public VeecoReader() {
super("Veeco", "hdf");
domains = new String[] {FormatTools.SEM_DOMAIN};
}
// -- IFormatReader API methods --
/**
* @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)
*/
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h)
throws FormatException, IOException
{
FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
if (image instanceof byte[][]) {
byte[][] byteImage = (byte[][]) image;
for (int row=h+y-1; row>=y; row--) {
System.arraycopy(byteImage[row], x, buf, (row - y) * w, w);
}
}
else if (image instanceof short[][]) {
short[][] shortImage = (short[][]) image;
int output = 0;
for (int row=h+y-1; row>=y; row--) {
for (int col=x; col<x+w; col++) {
DataTools.unpackBytes(
shortImage[row][col], buf, output, 2, unpackEndian);
output += 2;
}
}
}
return buf;
}
/* @see loci.formats.IFormatReader#close(boolean) */
public void close(boolean fileOnly) throws IOException {
super.close(fileOnly);
if (!fileOnly) {
if (netcdf != null) netcdf.close();
image = null;
unpackEndian = true;
}
}
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
CoreMetadata m = core.get(0);
try {
ServiceFactory factory = new ServiceFactory();
netcdf = factory.getInstance(NetCDFService.class);
netcdf.setFile(id);
}
catch (DependencyException e) {
throw new MissingLibraryException(e);
}
Vector<String> variableList = netcdf.getVariableList();
// a single variable containing the image data is expected
if (variableList.size() == 0) {
throw new FormatException("No image data found");
}
String imageName = variableList.get(0);
try {
image = netcdf.getVariableValue(imageName);
}
catch (ServiceException e) {
throw new FormatException("Could not retrieve image data", e);
}
Hashtable<String, Object> attributes =
netcdf.getVariableAttributes(imageName);
for (String attr : attributes.keySet()) {
addGlobalMeta(attr, attributes.get(attr));
}
if (image instanceof byte[][]) {
byte[][] byteImage = (byte[][]) image;
m.sizeX = byteImage[0].length;
m.sizeY = byteImage.length;
m.pixelType = FormatTools.INT8;
}
else if (image instanceof short[][]) {
short[][] shortImage = (short[][]) image;
m.sizeX = shortImage[0].length;
m.sizeY = shortImage.length;
m.pixelType = FormatTools.INT16;
// set the endianness to use when unpacking pixels
// NetCDF may not return the pixels with a constant endianness,
// so this ensures that the reader corrects accordingly (see ticket 12085)
short nativeMin = 0;
short nativeMax = 0;
short swappedMin = 0;
short swappedMax = 0;
for (int y=0; y<shortImage.length; y++) {
for (int x=0; x<shortImage[y].length; x++) {
if (shortImage[y][x] < nativeMin) {
nativeMin = shortImage[y][x];
}
if (shortImage[y][x] > nativeMax) {
nativeMax = shortImage[y][x];
}
short swapped = DataTools.swap(shortImage[y][x]);
if (swapped < swappedMin) {
swappedMin = swapped;
}
if (swapped > swappedMax) {
swappedMax = swapped;
}
}
}
unpackEndian = nativeMin <= swappedMin && nativeMax >= swappedMax;
}
m.sizeZ = 1;
m.sizeC = 1;
m.sizeT = 1;
m.imageCount = m.sizeZ * m.sizeC * m.sizeT;
m.dimensionOrder = "XYCZT";
m.littleEndian = false;
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
}
}