/* * Copyright (c) 2012 Diamond Light Source Ltd. * * 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 */ package org.eclipse.dawnsci.remotedataset.test.mock; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.util.Arrays; import java.util.Map; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.ImageTypeSpecifier; import org.eclipse.dawnsci.analysis.api.io.IDataHolder; import org.eclipse.dawnsci.analysis.api.io.ScanFileHolderException; import org.eclipse.january.IMonitor; import org.eclipse.january.dataset.IDataset; import org.eclipse.january.dataset.ILazyDataset; import org.eclipse.january.dataset.SliceND; /** * This class loads a TIFF image file */ public class MockImageLoader extends MockJavaImageLoader { protected Map<String, Serializable> metadataMap = null; private boolean loadData = true; private int height = -1; private int width = -1; public MockImageLoader() { this(null, false); } /** * @param FileName */ public MockImageLoader(String FileName) { this(FileName, false); } /** * @param FileName * @param convertToGrey */ public MockImageLoader(String FileName, boolean convertToGrey) { super(FileName, "tiff", convertToGrey); } /** * @param FileName * @param convertToGrey * @param keepBitWidth */ public MockImageLoader(String FileName, boolean convertToGrey, boolean keepBitWidth) { super(FileName, "tiff", convertToGrey, keepBitWidth); } @Override public IDataHolder loadFile() throws ScanFileHolderException { File f = null; // Check for file f = new File(fileName); if (!f.exists()) { logger.warn("File, {}, did not exist. Now trying to replace suffix", fileName); f = findCorrectSuffix(); } // TODO cope with multiple images (tiff) IDataHolder output = new MockDataHolder(null, fileName); ImageReader reader = null; try { int count = 0; try { BufferedImage image = ImageIO.read(f); IDataset set = SWTImageUtils.convertToRGBDataset(image); set.setName("image"); output.addDataset("image", set); } catch (Exception ne) { if (count>10) throw ne; count++; } } catch (IllegalArgumentException e) { throw new ScanFileHolderException("IllegalArgumentException interpreting file '" + fileName + "'", e); } catch (NullPointerException e) { throw new ScanFileHolderException("NullPointerException interpreting file '" + fileName + "'", e); } catch (Exception other) { System.out.println("> Cannot read "+fileName); other.printStackTrace(); throw new ScanFileHolderException("> Cannot read "+fileName, other); } finally { if (reader != null) reader.dispose(); } if (!loadData) { return null; } return output; } private void readImages(IDataHolder output, ImageReader reader) throws IOException, ScanFileHolderException { int n = reader.getNumImages(true); if (n == 0) { return; } if (!loadData) return; boolean allSame = true; if (height < 0 || width < 0) { height = reader.getHeight(0); // this can throw NPE when using 12-bit reader width = reader.getWidth(0); for (int i = 1; i < n; i++) { if (height != reader.getHeight(i) || width != reader.getWidth(i)) { allSame = false; break; } } } final ImageTypeSpecifier its = reader.getRawImageType(0); // this raises an exception for 12-bit images when using standard reader if (allSame) { for (int i = 1; i < n; i++) { if (!its.equals(reader.getRawImageType(i))) { throw new ScanFileHolderException("Type of image in stack does not match first"); } } } int dtype = AWTImageUtils.getDTypeFromImage(its.getSampleModel(), keepBitWidth)[0]; if (n == 1) { ILazyDataset image; if (loadLazily) { image = createLazyDataset(dtype, height, width); } else { image = createDataset(reader.read(0)); } image.setName(DEF_IMAGE_NAME); image.setMetadata(metadata); output.addDataset(DEF_IMAGE_NAME, image); } else if (allSame) { ILazyDataset ld = createLazyDataset(dtype, n, height, width); ld.setMetadata(metadata); output.addDataset(STACK_NAME, ld); } else { createLazyDatasets(output, reader); } if (loadMetadata) { createMetadata(output, reader); metadata.setMetadata(metadataMap); output.setMetadata(metadata); } } private ILazyDataset createLazyDataset(final int dtype, final int... trueShape) { LazyLoaderStub l = new LazyLoaderStub() { @Override public IDataset getDataset(IMonitor mon, SliceND slice) throws IOException { int[] lstart = slice.getStart(); int[] lstep = slice.getStep(); int[] newShape = slice.getShape(); int[] shape = slice.getSourceShape(); final int rank = shape.length; IDataset d = null; if (!Arrays.equals(trueShape, shape)) { final int trank = trueShape.length; int[] tstart = new int[trank]; int[] tsize = new int[trank]; int[] tstep = new int[trank]; if (rank > trank) { // shape was extended (from left) then need to translate to true slice int j = 0; for (int i = 0; i < trank; i++) { if (trueShape[i] == 1) { tstart[i] = 0; tsize[i] = 1; tstep[i] = 1; } else { while (shape[j] == 1 && (rank - j) > (trank - i)) j++; tstart[i] = lstart[j]; tsize[i] = newShape[j]; tstep[i] = lstep[j]; j++; } } } else { // shape was squeezed then need to translate to true slice int j = 0; for (int i = 0; i < trank; i++) { if (trueShape[i] == 1) { tstart[i] = 0; tsize[i] = 1; tstep[i] = 1; } else { tstart[i] = lstart[j]; tsize[i] = newShape[j]; tstep[i] = lstep[j]; j++; } } } d = loadData(mon, fileName, asGrey, keepBitWidth, dtype, shape, tstart, tsize, tstep); d.setShape(newShape); // squeeze shape back } else { d = loadData(mon, fileName, asGrey, keepBitWidth, dtype, shape, lstart, newShape, lstep); } return d; } }; return createLazyDataset(STACK_NAME, dtype, trueShape.clone(), l); } private static IDataset loadData(IMonitor mon, String filename, boolean asGrey, boolean keepBitWidth, int dtype, int[] oshape, int[] start, int[] count, int[] step) throws IOException { // test to see if the filename passed will load BufferedImage image = ImageIO.read(new File(filename)); IDataset set = SWTImageUtils.convertToRGBDataset(image); return set; } @Override protected void clearMetadata() { super.clearMetadata(); metadataMap.clear(); } }