All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.h5jan.io.JavaImageSaver Maven / Gradle / Ivy

/*
 * 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 io.github.h5jan.io;

import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;
import javax.media.jai.TiledImage;

import org.eclipse.january.IMonitor;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.IDataset;

import io.github.h5jan.core.DataFrame;

/**
 * Class that saves data from DataHolder using native Java ImageIO library
 * with built-in image reader/writer
 * 
 * If the DataHolder contains more than one dataset then multiple image
 * files are saved with names labelled from 00001 to 99999.
 */
class JavaImageSaver implements IStreamSaver {

	static {
		ImageIO.scanForPlugins(); // in case the ImageIO jar has not been loaded yet 
	}

	@Override
	public boolean save(OutputStream stream, Configuration conf, DataFrame dh, IMonitor monitor) throws IOException {
		
		String fileType = conf.getFileType(); // format name
		String fileName = conf.getFileName();
		
		int numBits = conf.getNumBits();
		boolean unsigned = conf.getAsUnsigned();
		double maxVal;
		if (numBits <= 32) {
			maxVal = (1L << numBits) - 1.0; // 2^NumBits - 1 (use long in case of overflow)
		} else {
			maxVal = 1.0; // flag to use doubles (TIFF only)
		}

		if (numBits <= 0) {
			throw new IOException(
					"Number of bits specified must be greater than 0");
		}

		for (int i = 0, imax = dh.size(); i < imax; i++) {

			try {
				String name = null;
				if (imax == 1) {
					name = fileName;
				} else {
					try {
						name = fileName.substring(0,
								(fileName.lastIndexOf(".")));
					} catch (Exception e) {
						name = fileName;
					}

					NumberFormat format = new DecimalFormat("00000");
					name = name + format.format(i + 1);
				}

				int l = new File(name).getName().lastIndexOf(".");
				if (l < 0) {
					name = name + "." + fileType.toLowerCase();
				}

				IDataset idata = dh.get(i).getSlice();
				Dataset data = DatasetUtils.convertToDataset(idata);

				if (numBits <= 16) {
					// test to see if the values of the data are within the
					// capabilities of format
					if (maxVal > 0 && data.max().doubleValue() > maxVal) {
						throw new IOException("The value of a pixel exceeds the maximum value that "
										+ fileType + " is capable of handling. To save a "
										+ fileType + " it is recommended to use a ScaledSaver class. File "
										+ fileName + " not written");
					}
					if (unsigned && data.min().doubleValue() < 0) {
						throw new IOException(
								"The value of a pixel is less than 0. Recommended using a ScaledSaver class.");
					}
					
					BufferedImage image = AWTImageUtils.makeBufferedImage(data, numBits);

					if (image == null) {
						throw new IOException("Unable to create a buffered image to save file type");
					}
					
					boolean w = writeImageLocked(image, fileType, stream, fileName, dh);
					if (!w)
						throw new IOException("No writer for '" + fileName + "' of type " + fileType);
				} else {
					TiledImage image = AWTImageUtils.makeTiledImage(data, numBits);

					if (image == null) {
						throw new IOException("Unable to create a tiled image to save file type");
					}
					boolean w = writeImageLocked(image, fileType, stream, fileName, dh);
					if (!w)
						throw new IOException("No writer for '" + fileName + "' of type " + fileType);
				}
			} catch (IOException e) {
				throw e;
			} catch (Exception e) {
				throw new IOException("Error saving file '" + fileName + "'", e);
			}

		}
		return true;
	}

	protected boolean writeImageLocked(RenderedImage image, String fileType, OutputStream out, String fileName, DataFrame dh) throws Exception {
		
		// Write meta data to image header
		if (image instanceof PlanarImage) {
			PlanarImage pi = (PlanarImage)image;
			if (fileName!=null) {
				pi.setProperty("originalDataSource", fileName);
			}

// TODO Write metadata
//			NxsMetadata meta = dh.getMetadata();
//			if (meta != null) {
//				Collection dNames = meta.getMetaNames();
//				if (dNames!=null) for (String name : dNames) {
//					pi.setProperty(name, meta.getMetaValue(name));
//				}
//			}
		}
		// Separate method added as may add file locking option.
		return ImageIO.write(image, fileType, out);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy