/* * 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.awt.image.DirectColorModel; import java.awt.image.IndexColorModel; import java.awt.image.WritableRaster; import org.eclipse.dawnsci.plotting.api.histogram.IImageService; import org.eclipse.dawnsci.plotting.api.histogram.ITransferFunction; import org.eclipse.dawnsci.plotting.api.histogram.ImageServiceBean; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.DatasetFactory; import org.eclipse.january.dataset.IndexIterator; import org.eclipse.january.dataset.RGBDataset; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.graphics.RGB; import org.eclipse.ui.PlatformUI; /** * Helper methods to convert to SWT images from datasets */ class SWTImageUtils { static private ImageData createImageFromRGBADataset(RGBDataset rgbdata, long minv, long maxv) { ImageData img; final IndexIterator iter = rgbdata.getIterator(true); final int[] pos = iter.getPos(); final int[] shape = rgbdata.getShape(); final int height = shape[0]; final int width = shape.length == 1 ? 1 : shape[1]; // allow 1D datasets to be saved long delta = maxv - minv; short off = (short) minv; short[] data = rgbdata.getData(); if (delta < 32) { // 555 img = new ImageData(width, height, 16, new PaletteData(0x7c00, 0x03e0, 0x001f)); while (iter.hasNext()) { final int n = iter.index; final int rgb = (((data[n] - off) & 0x1f) << 10) | (((data[n + 1] - off) & 0x1f) << 5) | ((data[n + 2] - off)& 0x1f); img.setPixel(pos[1], pos[0], rgb); } } else if (delta < 64) { // 565 img = new ImageData(width, height, 16, new PaletteData(0xf800, 0x07e0, 0x001f)); while (iter.hasNext()) { final int n = iter.index; final int rgb = ((((data[n] - off) >> 1) & 0x1f) << 10) | (((data[n + 1] - off) & 0x3f) << 5) | (((data[n + 2] - off) >> 1) & 0x1f); img.setPixel(pos[1], pos[0], rgb); } } else if (delta < 256) { // 888 img = new ImageData(width, height, 24, new PaletteData(0xff0000, 0x00ff00, 0x0000ff)); while (iter.hasNext()) { final int n = iter.index; final int rgb = (((data[n] - off) & 0xff) << 16) | (((data[n + 1] - off) & 0xff) << 8) | ((data[n + 2] - off) & 0xff); img.setPixel(pos[1], pos[0], rgb); } } else { int shift = 0; while (delta >= 256) { shift++; delta >>= 1; } img = new ImageData(width, height, 24, new PaletteData(0xff0000, 0x00ff00, 0x0000ff)); while (iter.hasNext()) { final int n = iter.index; final int rgb = ((((data[n] - off) >> shift) & 0xff) << 16) | ((((data[n + 1] - off) >> shift) & 0xff) << 8) | (((data[n + 2] - off) >> shift) & 0xff); img.setPixel(pos[1], pos[0], rgb); } } return img; } static private ImageData createImageFromDataset(Dataset a, double minv, double maxv, ITransferFunction redFunc, ITransferFunction greenFunc, ITransferFunction blueFunc, boolean inverseRed, boolean inverseGreen, boolean inverseBlue) { final int[] shape = a.getShape(); final int height = shape[0]; final int width = shape.length == 1 ? 1 : shape[1]; // allow 1D datasets to be saved ImageData img; final IndexIterator iter = a.getIterator(true); final int[] pos = iter.getPos(); img = new ImageData(width, height, 24, new PaletteData(0xff0000, 0x00ff00, 0x0000ff)); double delta = maxv - minv; while (iter.hasNext()) { double value = (a.getElementDoubleAbs(iter.index) - minv)/delta; final int red = (inverseRed ? (255-redFunc.mapToByte(value)) : redFunc.mapToByte(value)); final int green = (inverseGreen ? (255-greenFunc.mapToByte(value)) : greenFunc.mapToByte(value)); final int blue = (inverseBlue ? (255-blueFunc.mapToByte(value)) : blueFunc.mapToByte(value)); final int rgb = (red << 16) | green << 8 | blue; img.setPixel(pos[1], pos[0],rgb); } return img; } static private ImageData createImageFromDataset(Dataset a, PaletteData paletteData) throws Exception { final IImageService iservice = (IImageService)PlatformUI.getWorkbench().getService(IImageService.class); ImageServiceBean ibean = new ImageServiceBean(); ibean.setImage(a); ibean.setPalette(paletteData); return iservice.getImageData(ibean); } /** * Create SWT ImageData from a dataset * <p> * The input dataset can be a RGB dataset in which case the mapping functions * and inversion flags are ignored. * @param a dataset * @param max maximum value of dataset * @param redFunc * @param greenFunc * @param blueFunc * @param inverseRed * @param inverseGreen * @param inverseBlue * @return an ImageData object for SWT */ static public ImageData createImageData(Dataset a, Number max, ITransferFunction redFunc, ITransferFunction greenFunc, ITransferFunction blueFunc, boolean inverseRed, boolean inverseGreen, boolean inverseBlue) { return createImageData(a, 0, max, redFunc, greenFunc, blueFunc, inverseRed, inverseGreen, inverseBlue); } /** * Create SWT ImageData from a dataset * <p> * The input dataset can be a RGB dataset in which case the mapping functions * and inversion flags are ignored. * @param a dataset * @param min minimum value of dataset * @param max maximum value of dataset * @param redFunc * @param greenFunc * @param blueFunc * @param inverseRed * @param inverseGreen * @param inverseBlue * @return an ImageData object for SWT */ static public ImageData createImageData(Dataset a, Number min, Number max, ITransferFunction redFunc, ITransferFunction greenFunc, ITransferFunction blueFunc, boolean inverseRed, boolean inverseGreen, boolean inverseBlue) { ImageData img; if (a instanceof RGBDataset) { img = createImageFromRGBADataset((RGBDataset)a, min.longValue(), max.longValue()); } else { img = createImageFromDataset(a, min.doubleValue(), max.doubleValue(),redFunc,greenFunc,blueFunc, inverseRed,inverseGreen,inverseBlue); } return img; } /** * Create SWT ImageData from a dataset given a palette data * <p> * The input dataset can be a RGB dataset in which case the mapping functions * and inversion flags are ignored. * @param a dataset * @param min minimum value of dataset * @param max maximum value of dataset * @param paletteData * @return an ImageData object for SWT * @throws Exception */ static public ImageData createImageData(Dataset a, Number min, Number max, PaletteData paletteData) throws Exception { ImageData img; if (a instanceof RGBDataset) { img = createImageFromRGBADataset((RGBDataset)a, min.longValue(), max.longValue()); } else { img = createImageFromDataset(a, paletteData); } return img; } /** * Create RGB dataset from an SWT image * @param image * @return a RGB dataset */ static public RGBDataset createRGBDataset(final ImageData image) { final int[] data = new int[image.width]; final RGBDataset rgb = DatasetFactory.zeros(RGBDataset.class, image.height, image.width); final short[] p = new short[3]; final PaletteData palette = image.palette; if (palette.isDirect) { for (int i = 0; i < image.height; i++) { image.getPixels(0, i, image.width, data, 0); for (int j = 0; j < image.width; j++) { int value = data[j]; p[0] = palette.redShift >= 0 ? (short) ((value & palette.redMask) << palette.redShift) : (short) ((value & palette.redMask) >>> -palette.redShift); p[1] = palette.greenShift >= 0 ? (short) ((value & palette.greenMask) << palette.greenShift) : (short) ((value & palette.greenMask) >>> -palette.greenShift); p[2] = palette.blueShift >= 0 ? (short) ((value & palette.blueMask) << palette.blueShift) : (short) ((value & palette.blueMask) >>> -palette.blueShift); rgb.setItem(p, i, j); } } } else { final RGB[] table = palette.getRGBs(); for (int i = 0; i < image.height; i++) { image.getPixels(0, i, image.width, data, 0); for (int j = 0; j < image.width; j++) { RGB value = table[data[j]]; p[0] = (short) value.red; p[1] = (short) value.green; p[2] = (short) value.blue; rgb.setItem(p, i, j); } } } return rgb; } static RGBDataset convertToRGBDataset(BufferedImage bufferedImage) { RGBDataset data = DatasetFactory.zeros(RGBDataset.class, bufferedImage.getHeight(), bufferedImage.getWidth()); if (bufferedImage.getColorModel() instanceof DirectColorModel) { DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel(); for (int y = 0; y < bufferedImage.getHeight(); y++) { for (int x = 0; x < bufferedImage.getWidth(); x++) { int value = bufferedImage.getRGB(x, y); RGB rgb = new RGB((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF); data.set(new short[]{(short)rgb.red, (short)rgb.green, (short)rgb.blue}, y, x); if (colorModel.hasAlpha()) { // TODO //data.set(x, y, (rgb >> 24) & 0xFF); } } } return data; } else if (bufferedImage.getColorModel() instanceof IndexColorModel) { IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel(); int size = colorModel.getMapSize(); byte[] reds = new byte[size]; byte[] greens = new byte[size]; byte[] blues = new byte[size]; colorModel.getReds(reds); colorModel.getGreens(greens); colorModel.getBlues(blues); RGB[] rgbs = new RGB[size]; for (int i = 0; i < rgbs.length; i++) { rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF); } PaletteData palette = new PaletteData(rgbs); WritableRaster raster = bufferedImage.getRaster(); int[] pixelArray = new int[1]; for (int y = 0; y < bufferedImage.getHeight(); y++) { for (int x = 0; x < bufferedImage.getWidth(); x++) { raster.getPixel(x, y, pixelArray); RGB rgb = palette.getRGB(pixelArray[0]); data.set(new short[]{(short)rgb.red, (short)rgb.green, (short)rgb.blue}, y, x); } } } else { WritableRaster raster = bufferedImage.getRaster(); int[] pixelArray = new int[3]; for (int y = 0; y < bufferedImage.getHeight(); y++) { for (int x = 0; x < bufferedImage.getWidth(); x++) { raster.getPixel(x, y, pixelArray); data.set(new short[]{ (short)pixelArray[0], (short)pixelArray[1], (short)pixelArray[2]}, y, x); } } } return data; } }