/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy 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 3 of the License, or
* (at your option) any later version.
*
* Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.type;
import icy.math.MathUtil;
import icy.vtk.VtkUtil;
import java.awt.image.DataBuffer;
import java.util.ArrayList;
import loci.formats.FormatTools;
import ome.xml.model.enums.PixelType;
/**
* DataType class.<br>
* This class is used to define the internal native data type of a given object.
*
* @author Stephane
*/
public enum DataType
{
// UBYTE (unsigned 8 bits integer)
UBYTE(Byte.SIZE, true, false, 0d, MathUtil.POW2_8_DOUBLE - 1d, Byte.TYPE, DataBuffer.TYPE_BYTE, PixelType.UINT8,
"unsigned byte (8 bits)", "8 bits"),
// BYTE (signed 8 bits integer)
BYTE(Byte.SIZE, true, true, Byte.MIN_VALUE, Byte.MAX_VALUE, Byte.TYPE, DataBuffer.TYPE_BYTE, PixelType.INT8,
"signed byte (8 bits)", "8 bits (signed)"),
// USHORT (unsigned 16 bits integer)
USHORT(Short.SIZE, true, false, 0d, MathUtil.POW2_16_DOUBLE - 1d, Short.TYPE, DataBuffer.TYPE_USHORT,
PixelType.UINT16, "unsigned short (16 bits)", "16 bits"),
// SHORT (signed 16 bits integer)
SHORT(Short.SIZE, true, true, Short.MIN_VALUE, Short.MAX_VALUE, Short.TYPE, DataBuffer.TYPE_SHORT, PixelType.INT16,
"signed short (16 bits)", "16 bits (signed)"),
// UINT (unsigned 32bits integer)
UINT(Integer.SIZE, true, false, 0d, MathUtil.POW2_32_DOUBLE - 1d, Integer.TYPE, DataBuffer.TYPE_INT,
PixelType.UINT32, "unsigned int (32 bits)", "32 bits"),
// INT (signed 32 bits integer)
INT(Integer.SIZE, true, true, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.TYPE, DataBuffer.TYPE_INT,
PixelType.INT32, "signed int (32 bits)", "32 bits (signed)"),
// ULONG (unsigned 64 bits integer)
// WARNING : double data type loss information here for min/max
ULONG(Long.SIZE, true, false, 0d, MathUtil.POW2_64_DOUBLE - 1d, Long.TYPE, DataBuffer.TYPE_UNDEFINED, null,
"unsigned long (64 bits)", "64 bits"),
// LONG (signed 64 bits integer)
// WARNING : double data type loss information here for min/max
LONG(Long.SIZE, true, true, Long.MIN_VALUE, Long.MAX_VALUE, Long.TYPE, DataBuffer.TYPE_UNDEFINED, null,
"signed long (64 bits)", "64 bits (signed)"),
// FLOAT (signed 32 bits float)
FLOAT(Float.SIZE, false, true, -Float.MAX_VALUE, Float.MAX_VALUE, Float.TYPE, DataBuffer.TYPE_FLOAT,
PixelType.FLOAT, "float (32 bits)", "float"),
// DOUBLE (signed 64 bits float)
DOUBLE(Double.SIZE, false, true, -Double.MAX_VALUE, Double.MAX_VALUE, Double.TYPE, DataBuffer.TYPE_DOUBLE,
PixelType.DOUBLE, "double (64 bits)", "double"),
// UNDEFINED (undefined data type)
/**
* @deprecated Use <code>null</code> instance instead
*/
@SuppressWarnings("dep-ann")
UNDEFINED(0, true, false, 0d, 0d, null, DataBuffer.TYPE_UNDEFINED, null, "undefined", "undefined");
/**
* cached
*/
public static final double UBYTE_MAX_VALUE = MathUtil.POW2_8_DOUBLE - 1;
public static final double USHORT_MAX_VALUE = MathUtil.POW2_16_DOUBLE - 1;
public static final double UINT_MAX_VALUE = MathUtil.POW2_32_DOUBLE - 1;
public static final double ULONG_MAX_VALUE = MathUtil.POW2_64_DOUBLE - 1;
public static final double INT_MIN_VALUE = Integer.MIN_VALUE;
public static final double LONG_MIN_VALUE = Long.MIN_VALUE;
public static final double INT_MAX_VALUE = Integer.MAX_VALUE;
public static final double LONG_MAX_VALUE = Long.MAX_VALUE;
public static final float UBYTE_MAX_VALUE_F = MathUtil.POW2_8_FLOAT - 1;
public static final float USHORT_MAX_VALUE_F = MathUtil.POW2_16_FLOAT - 1;
public static final float UINT_MAX_VALUE_F = MathUtil.POW2_32_FLOAT - 1;
public static final float ULONG_MAX_VALUE_F = MathUtil.POW2_64_FLOAT - 1;
public static final float INT_MIN_VALUE_F = Integer.MIN_VALUE;
public static final float LONG_MIN_VALUE_F = Long.MIN_VALUE;
public static final float INT_MAX_VALUE_F = Integer.MAX_VALUE;
public static final float LONG_MAX_VALUE_F = Long.MAX_VALUE;
/**
* Return all dataType as String items array (can be used for ComboBox).<br>
*
* @param javaTypeOnly
* Define if we want only java compatible data type (no unsigned integer types)
* @param longString
* Define if we want long string format (bpp information)
* @param wantUndef
* Define if we want the UNDEFINED data type in the list
*/
public static String[] getItems(boolean javaTypeOnly, boolean longString, boolean wantUndef)
{
final ArrayList<String> result = new ArrayList<String>();
for (DataType dataType : DataType.values())
if (((!javaTypeOnly) || dataType.isJavaType()) && (wantUndef || (dataType != UNDEFINED)))
result.add(dataType.toString(longString));
return result.toArray(new String[result.size()]);
}
/**
* Return a DataType from the specified string.<br>
* ex : <code>getDataType("byte")</code> will return <code>DataType.BYTE</code>
*/
public static DataType getDataType(String value)
{
for (DataType dataType : DataType.values())
if (dataType.toString(false).equals(value) || dataType.toString(true).equals(value))
return dataType;
return null;
}
/**
* Return a DataType from old dataType.<br>
* ex : <code>getDataTypeFromOldDataType(TypeUtil.BYTE, false)</code> will return <code>DataType.UBYTE</code>
*/
public static DataType getDataType(int oldDataType, boolean signed)
{
switch (oldDataType)
{
case TypeUtil.TYPE_BYTE:
if (signed)
return BYTE;
return UBYTE;
case TypeUtil.TYPE_SHORT:
if (signed)
return SHORT;
return USHORT;
case TypeUtil.TYPE_INT:
if (signed)
return INT;
return UINT;
case TypeUtil.TYPE_FLOAT:
return FLOAT;
case TypeUtil.TYPE_DOUBLE:
return DOUBLE;
default:
return null;
}
}
/**
* Return a DataType from old dataType.<br>
* ex : <code>getDataType(TypeUtil.BYTE)</code> will return <code>DataType.BYTE</code>
*/
public static DataType getDataType(int oldDataType)
{
return getDataType(oldDataType, true);
}
/**
* Return a DataType from the specified primitive class type
*/
public static DataType getDataType(Class<?> classType)
{
if (classType.equals(java.lang.Byte.TYPE))
return DataType.BYTE;
if (classType.equals(java.lang.Short.TYPE))
return DataType.SHORT;
if (classType.equals(java.lang.Integer.TYPE))
return DataType.INT;
if (classType.equals(java.lang.Long.TYPE))
return DataType.LONG;
if (classType.equals(java.lang.Float.TYPE))
return DataType.FLOAT;
if (classType.equals(java.lang.Double.TYPE))
return DataType.DOUBLE;
return null;
}
/**
* Return a DataType from the specified VTK type.<br>
* ex : <code>getDataTypeFromVTKType(VtkUtil.VTK_INT)</code> will return <code>DataType.INT</code>
*/
public static DataType getDataTypeFromVTKType(int vtkType)
{
switch (vtkType)
{
case VtkUtil.VTK_UNSIGNED_CHAR:
return UBYTE;
case VtkUtil.VTK_CHAR:
case VtkUtil.VTK_SIGNED_CHAR:
return BYTE;
case VtkUtil.VTK_UNSIGNED_SHORT:
return USHORT;
case VtkUtil.VTK_SHORT:
return SHORT;
case VtkUtil.VTK_UNSIGNED_INT:
return UINT;
case VtkUtil.VTK_INT:
return INT;
case VtkUtil.VTK_FLOAT:
return FLOAT;
case VtkUtil.VTK_DOUBLE:
return DOUBLE;
case VtkUtil.VTK_UNSIGNED_LONG:
return ULONG;
case VtkUtil.VTK_LONG:
return LONG;
default:
return null;
}
}
/**
* Return a DataType from the specified DataBuffer type.<br>
* ex : <code>getDataTypeFromDataBufferType(DataBuffer.TYPE_BYTE)</code> will return <code>DataType.UBYTE</code>
*/
public static DataType getDataTypeFromDataBufferType(int dataBufferType)
{
switch (dataBufferType)
{
case DataBuffer.TYPE_BYTE:
// consider as unsigned by default
return UBYTE;
case DataBuffer.TYPE_SHORT:
return SHORT;
case DataBuffer.TYPE_USHORT:
return USHORT;
case DataBuffer.TYPE_INT:
// consider as unsigned by default
return UINT;
case DataBuffer.TYPE_FLOAT:
return FLOAT;
case DataBuffer.TYPE_DOUBLE:
return DOUBLE;
default:
return null;
}
}
/**
* Return a DataType from the specified FormatTools type.<br>
* ex : <code>getDataTypeFromFormatToolsType(FormatTools.UINT8)</code> will return <code>DataType.UBYTE</code>
*/
public static DataType getDataTypeFromFormatToolsType(int type)
{
switch (type)
{
case FormatTools.INT8:
return BYTE;
case FormatTools.UINT8:
return UBYTE;
case FormatTools.INT16:
return SHORT;
case FormatTools.UINT16:
return USHORT;
case FormatTools.INT32:
return INT;
case FormatTools.UINT32:
return UINT;
case FormatTools.FLOAT:
return FLOAT;
case FormatTools.DOUBLE:
return DOUBLE;
default:
return null;
}
}
/**
* Return a DataType from the specified PixelType.<br>
* ex : <code>getDataTypeFromPixelType(FormatTools.UINT8)</code> will return <code>DataType.UBYTE</code>
*/
public static DataType getDataTypeFromPixelType(PixelType type)
{
switch (type)
{
case INT8:
return BYTE;
case UINT8:
return UBYTE;
case INT16:
return SHORT;
case UINT16:
return USHORT;
case INT32:
return INT;
case UINT32:
return UINT;
case FLOAT:
return FLOAT;
case DOUBLE:
return DOUBLE;
default:
return null;
}
}
/**
* internals properties
*/
protected String longString;
protected String string;
protected int bitSize;
protected boolean integer;
protected boolean signed;
protected double min;
protected double max;
protected Class<?> primitiveClass;
protected int dataBufferType;
protected PixelType pixelType;
private DataType(int bitSize, boolean integer, boolean signed, double min, double max, Class<?> primitiveClass,
int dataBufferType, PixelType pixelType, String longString, String string)
{
this.bitSize = bitSize;
this.integer = integer;
this.signed = signed;
this.min = min;
this.max = max;
this.primitiveClass = primitiveClass;
this.dataBufferType = dataBufferType;
this.pixelType = pixelType;
this.longString = longString;
this.string = string;
}
/**
* Return the java compatible data type (signed integer type only).<br>
* Can be only one of the following :<br>
* {@link DataType#BYTE}<br>
* {@link DataType#SHORT}<br>
* {@link DataType#INT}<br>
* {@link DataType#LONG}<br>
* {@link DataType#FLOAT}<br>
* {@link DataType#DOUBLE}<br>
*/
public DataType getJavaType()
{
switch (this)
{
case UBYTE:
return BYTE;
case USHORT:
return SHORT;
case UINT:
return INT;
case ULONG:
return LONG;
default:
return this;
}
}
/**
* Return the minimum value for current DataType
*/
public double getMinValue()
{
return min;
}
/**
* Return the maximum value for current DataType
*/
public double getMaxValue()
{
return max;
}
/**
* Get the default bounds for current DataType.<br>
* This actually returns <code>[0,1]</code> for Float or Double DataType.
*/
public double[] getDefaultBounds()
{
if (!integer)
return new double[] {0d, 1d};
return new double[] {getMinValue(), getMaxValue()};
}
/**
* Get the bounds <code>[min,max]</code> for current DataType.
*/
public double[] getBounds()
{
return new double[] {getMinValue(), getMaxValue()};
}
/**
* Return true if this is a compatible java data type (signed integer type only)
*/
public boolean isJavaType()
{
return this == getJavaType();
}
/**
* Return true if this is a signed data type
*/
public boolean isSigned()
{
return signed;
}
/**
* Return true if this is a float data type
*/
public boolean isFloat()
{
return !isInteger();
}
/**
* Return true if this is an integer data type
*/
public boolean isInteger()
{
return integer;
}
/**
* @deprecated Use {@link #getSize()} instead
*/
@Deprecated
public int sizeOf()
{
return getSize();
}
/**
* Return the size (in byte) of the specified dataType
*/
public int getSize()
{
return getBitSize() / 8;
}
/**
* Return the size (in bit) of the specified dataType
*/
public int getBitSize()
{
return bitSize;
}
/**
* Return true if specified data type has same "basic" type (no sign information) data type
*/
public boolean isSameJavaType(DataType dataType)
{
return dataType.getJavaType() == getJavaType();
}
/**
* Return the corresponding primitive class type corresponding to this DataType.
*/
public Class<?> toPrimitiveClass()
{
return primitiveClass;
}
/**
* Return the DataBuffer type corresponding to current DataType
*/
public int toDataBufferType()
{
return dataBufferType;
}
/**
* Return the PixelType corresponding to current DataType
*/
public PixelType toPixelType()
{
return pixelType;
}
/**
* Convert DataType to String.<br>
*
* @param longString
* Define if we want long description (bpp information)
*/
public String toString(boolean longString)
{
if (longString)
return toLongString();
return toString();
}
/**
* Convert DataType to long String (long description with bpp information)
*/
public String toLongString()
{
return longString;
}
@Override
public String toString()
{
return string;
}
}