001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.type; 020 021import icy.math.MathUtil; 022import icy.vtk.VtkUtil; 023 024import java.awt.image.DataBuffer; 025import java.util.ArrayList; 026 027import loci.formats.FormatTools; 028import ome.xml.model.enums.PixelType; 029 030/** 031 * DataType class.<br> 032 * This class is used to define the internal native data type of a given object. 033 * 034 * @author Stephane 035 */ 036public enum DataType 037{ 038 // UBYTE (unsigned 8 bits integer) 039 UBYTE(Byte.SIZE, true, false, 0d, MathUtil.POW2_8_DOUBLE - 1d, Byte.TYPE, DataBuffer.TYPE_BYTE, PixelType.UINT8, 040 "unsigned byte (8 bits)", "8 bits"), 041 // BYTE (signed 8 bits integer) 042 BYTE(Byte.SIZE, true, true, Byte.MIN_VALUE, Byte.MAX_VALUE, Byte.TYPE, DataBuffer.TYPE_BYTE, PixelType.INT8, 043 "signed byte (8 bits)", "8 bits (signed)"), 044 // USHORT (unsigned 16 bits integer) 045 USHORT(Short.SIZE, true, false, 0d, MathUtil.POW2_16_DOUBLE - 1d, Short.TYPE, DataBuffer.TYPE_USHORT, 046 PixelType.UINT16, "unsigned short (16 bits)", "16 bits"), 047 // SHORT (signed 16 bits integer) 048 SHORT(Short.SIZE, true, true, Short.MIN_VALUE, Short.MAX_VALUE, Short.TYPE, DataBuffer.TYPE_SHORT, PixelType.INT16, 049 "signed short (16 bits)", "16 bits (signed)"), 050 // UINT (unsigned 32bits integer) 051 UINT(Integer.SIZE, true, false, 0d, MathUtil.POW2_32_DOUBLE - 1d, Integer.TYPE, DataBuffer.TYPE_INT, 052 PixelType.UINT32, "unsigned int (32 bits)", "32 bits"), 053 // INT (signed 32 bits integer) 054 INT(Integer.SIZE, true, true, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.TYPE, DataBuffer.TYPE_INT, 055 PixelType.INT32, "signed int (32 bits)", "32 bits (signed)"), 056 // ULONG (unsigned 64 bits integer) 057 // WARNING : double data type loss information here for min/max 058 ULONG(Long.SIZE, true, false, 0d, MathUtil.POW2_64_DOUBLE - 1d, Long.TYPE, DataBuffer.TYPE_UNDEFINED, null, 059 "unsigned long (64 bits)", "64 bits"), 060 // LONG (signed 64 bits integer) 061 // WARNING : double data type loss information here for min/max 062 LONG(Long.SIZE, true, true, Long.MIN_VALUE, Long.MAX_VALUE, Long.TYPE, DataBuffer.TYPE_UNDEFINED, null, 063 "signed long (64 bits)", "64 bits (signed)"), 064 // FLOAT (signed 32 bits float) 065 FLOAT(Float.SIZE, false, true, -Float.MAX_VALUE, Float.MAX_VALUE, Float.TYPE, DataBuffer.TYPE_FLOAT, 066 PixelType.FLOAT, "float (32 bits)", "float"), 067 // DOUBLE (signed 64 bits float) 068 DOUBLE(Double.SIZE, false, true, -Double.MAX_VALUE, Double.MAX_VALUE, Double.TYPE, DataBuffer.TYPE_DOUBLE, 069 PixelType.DOUBLE, "double (64 bits)", "double"), 070 // UNDEFINED (undefined data type) 071 /** 072 * @deprecated Use <code>null</code> instance instead 073 */ 074 @SuppressWarnings("dep-ann") 075 UNDEFINED(0, true, false, 0d, 0d, null, DataBuffer.TYPE_UNDEFINED, null, "undefined", "undefined"); 076 077 /** 078 * cached 079 */ 080 public static final double UBYTE_MAX_VALUE = MathUtil.POW2_8_DOUBLE - 1; 081 public static final double USHORT_MAX_VALUE = MathUtil.POW2_16_DOUBLE - 1; 082 public static final double UINT_MAX_VALUE = MathUtil.POW2_32_DOUBLE - 1; 083 public static final double ULONG_MAX_VALUE = MathUtil.POW2_64_DOUBLE - 1; 084 public static final double INT_MIN_VALUE = Integer.MIN_VALUE; 085 public static final double LONG_MIN_VALUE = Long.MIN_VALUE; 086 public static final double INT_MAX_VALUE = Integer.MAX_VALUE; 087 public static final double LONG_MAX_VALUE = Long.MAX_VALUE; 088 089 public static final float UBYTE_MAX_VALUE_F = MathUtil.POW2_8_FLOAT - 1; 090 public static final float USHORT_MAX_VALUE_F = MathUtil.POW2_16_FLOAT - 1; 091 public static final float UINT_MAX_VALUE_F = MathUtil.POW2_32_FLOAT - 1; 092 public static final float ULONG_MAX_VALUE_F = MathUtil.POW2_64_FLOAT - 1; 093 public static final float INT_MIN_VALUE_F = Integer.MIN_VALUE; 094 public static final float LONG_MIN_VALUE_F = Long.MIN_VALUE; 095 public static final float INT_MAX_VALUE_F = Integer.MAX_VALUE; 096 public static final float LONG_MAX_VALUE_F = Long.MAX_VALUE; 097 098 /** 099 * Return all dataType as String items array (can be used for ComboBox).<br> 100 * 101 * @param javaTypeOnly 102 * Define if we want only java compatible data type (no unsigned integer types) 103 * @param longString 104 * Define if we want long string format (bpp information) 105 * @param wantUndef 106 * Define if we want the UNDEFINED data type in the list 107 */ 108 public static String[] getItems(boolean javaTypeOnly, boolean longString, boolean wantUndef) 109 { 110 final ArrayList<String> result = new ArrayList<String>(); 111 112 for (DataType dataType : DataType.values()) 113 if (((!javaTypeOnly) || dataType.isJavaType()) && (wantUndef || (dataType != UNDEFINED))) 114 result.add(dataType.toString(longString)); 115 116 return result.toArray(new String[result.size()]); 117 } 118 119 /** 120 * Return a DataType from the specified string.<br> 121 * ex : <code>getDataType("byte")</code> will return <code>DataType.BYTE</code> 122 */ 123 public static DataType getDataType(String value) 124 { 125 for (DataType dataType : DataType.values()) 126 if (dataType.toString(false).equals(value) || dataType.toString(true).equals(value)) 127 return dataType; 128 129 return null; 130 } 131 132 /** 133 * Return a DataType from old dataType.<br> 134 * ex : <code>getDataTypeFromOldDataType(TypeUtil.BYTE, false)</code> will return <code>DataType.UBYTE</code> 135 */ 136 public static DataType getDataType(int oldDataType, boolean signed) 137 { 138 switch (oldDataType) 139 { 140 case TypeUtil.TYPE_BYTE: 141 if (signed) 142 return BYTE; 143 return UBYTE; 144 case TypeUtil.TYPE_SHORT: 145 if (signed) 146 return SHORT; 147 return USHORT; 148 case TypeUtil.TYPE_INT: 149 if (signed) 150 return INT; 151 return UINT; 152 case TypeUtil.TYPE_FLOAT: 153 return FLOAT; 154 case TypeUtil.TYPE_DOUBLE: 155 return DOUBLE; 156 default: 157 return null; 158 } 159 } 160 161 /** 162 * Return a DataType from old dataType.<br> 163 * ex : <code>getDataType(TypeUtil.BYTE)</code> will return <code>DataType.BYTE</code> 164 */ 165 public static DataType getDataType(int oldDataType) 166 { 167 return getDataType(oldDataType, true); 168 } 169 170 /** 171 * Return a DataType from the specified primitive class type 172 */ 173 public static DataType getDataType(Class<?> classType) 174 { 175 if (classType.equals(java.lang.Byte.TYPE)) 176 return DataType.BYTE; 177 if (classType.equals(java.lang.Short.TYPE)) 178 return DataType.SHORT; 179 if (classType.equals(java.lang.Integer.TYPE)) 180 return DataType.INT; 181 if (classType.equals(java.lang.Long.TYPE)) 182 return DataType.LONG; 183 if (classType.equals(java.lang.Float.TYPE)) 184 return DataType.FLOAT; 185 if (classType.equals(java.lang.Double.TYPE)) 186 return DataType.DOUBLE; 187 188 return null; 189 } 190 191 /** 192 * Return a DataType from the specified VTK type.<br> 193 * ex : <code>getDataTypeFromVTKType(VtkUtil.VTK_INT)</code> will return <code>DataType.INT</code> 194 */ 195 public static DataType getDataTypeFromVTKType(int vtkType) 196 { 197 switch (vtkType) 198 { 199 case VtkUtil.VTK_UNSIGNED_CHAR: 200 return UBYTE; 201 case VtkUtil.VTK_CHAR: 202 case VtkUtil.VTK_SIGNED_CHAR: 203 return BYTE; 204 case VtkUtil.VTK_UNSIGNED_SHORT: 205 return USHORT; 206 case VtkUtil.VTK_SHORT: 207 return SHORT; 208 case VtkUtil.VTK_UNSIGNED_INT: 209 return UINT; 210 case VtkUtil.VTK_INT: 211 return INT; 212 case VtkUtil.VTK_FLOAT: 213 return FLOAT; 214 case VtkUtil.VTK_DOUBLE: 215 return DOUBLE; 216 case VtkUtil.VTK_UNSIGNED_LONG: 217 return ULONG; 218 case VtkUtil.VTK_LONG: 219 return LONG; 220 default: 221 return null; 222 } 223 } 224 225 /** 226 * Return a DataType from the specified DataBuffer type.<br> 227 * ex : <code>getDataTypeFromDataBufferType(DataBuffer.TYPE_BYTE)</code> will return <code>DataType.UBYTE</code> 228 */ 229 public static DataType getDataTypeFromDataBufferType(int dataBufferType) 230 { 231 switch (dataBufferType) 232 { 233 case DataBuffer.TYPE_BYTE: 234 // consider as unsigned by default 235 return UBYTE; 236 case DataBuffer.TYPE_SHORT: 237 return SHORT; 238 case DataBuffer.TYPE_USHORT: 239 return USHORT; 240 case DataBuffer.TYPE_INT: 241 // consider as unsigned by default 242 return UINT; 243 case DataBuffer.TYPE_FLOAT: 244 return FLOAT; 245 case DataBuffer.TYPE_DOUBLE: 246 return DOUBLE; 247 default: 248 return null; 249 } 250 } 251 252 /** 253 * Return a DataType from the specified FormatTools type.<br> 254 * ex : <code>getDataTypeFromFormatToolsType(FormatTools.UINT8)</code> will return <code>DataType.UBYTE</code> 255 */ 256 public static DataType getDataTypeFromFormatToolsType(int type) 257 { 258 switch (type) 259 { 260 case FormatTools.INT8: 261 return BYTE; 262 case FormatTools.UINT8: 263 return UBYTE; 264 case FormatTools.INT16: 265 return SHORT; 266 case FormatTools.UINT16: 267 return USHORT; 268 case FormatTools.INT32: 269 return INT; 270 case FormatTools.UINT32: 271 return UINT; 272 case FormatTools.FLOAT: 273 return FLOAT; 274 case FormatTools.DOUBLE: 275 return DOUBLE; 276 default: 277 return null; 278 } 279 } 280 281 /** 282 * Return a DataType from the specified PixelType.<br> 283 * ex : <code>getDataTypeFromPixelType(FormatTools.UINT8)</code> will return <code>DataType.UBYTE</code> 284 */ 285 public static DataType getDataTypeFromPixelType(PixelType type) 286 { 287 switch (type) 288 { 289 case INT8: 290 return BYTE; 291 case UINT8: 292 return UBYTE; 293 case INT16: 294 return SHORT; 295 case UINT16: 296 return USHORT; 297 case INT32: 298 return INT; 299 case UINT32: 300 return UINT; 301 case FLOAT: 302 return FLOAT; 303 case DOUBLE: 304 return DOUBLE; 305 default: 306 return null; 307 } 308 } 309 310 /** 311 * internals properties 312 */ 313 protected String longString; 314 protected String string; 315 protected int bitSize; 316 protected boolean integer; 317 protected boolean signed; 318 protected double min; 319 protected double max; 320 protected Class<?> primitiveClass; 321 protected int dataBufferType; 322 protected PixelType pixelType; 323 324 private DataType(int bitSize, boolean integer, boolean signed, double min, double max, Class<?> primitiveClass, 325 int dataBufferType, PixelType pixelType, String longString, String string) 326 { 327 this.bitSize = bitSize; 328 this.integer = integer; 329 this.signed = signed; 330 this.min = min; 331 this.max = max; 332 this.primitiveClass = primitiveClass; 333 this.dataBufferType = dataBufferType; 334 this.pixelType = pixelType; 335 this.longString = longString; 336 this.string = string; 337 } 338 339 /** 340 * Return the java compatible data type (signed integer type only).<br> 341 * Can be only one of the following :<br> 342 * {@link DataType#BYTE}<br> 343 * {@link DataType#SHORT}<br> 344 * {@link DataType#INT}<br> 345 * {@link DataType#LONG}<br> 346 * {@link DataType#FLOAT}<br> 347 * {@link DataType#DOUBLE}<br> 348 */ 349 public DataType getJavaType() 350 { 351 switch (this) 352 { 353 case UBYTE: 354 return BYTE; 355 case USHORT: 356 return SHORT; 357 case UINT: 358 return INT; 359 case ULONG: 360 return LONG; 361 362 default: 363 return this; 364 } 365 } 366 367 /** 368 * Return the minimum value for current DataType 369 */ 370 public double getMinValue() 371 { 372 return min; 373 } 374 375 /** 376 * Return the maximum value for current DataType 377 */ 378 public double getMaxValue() 379 { 380 return max; 381 } 382 383 /** 384 * Get the default bounds for current DataType.<br> 385 * This actually returns <code>[0,1]</code> for Float or Double DataType. 386 */ 387 public double[] getDefaultBounds() 388 { 389 if (!integer) 390 return new double[] {0d, 1d}; 391 392 return new double[] {getMinValue(), getMaxValue()}; 393 } 394 395 /** 396 * Get the bounds <code>[min,max]</code> for current DataType. 397 */ 398 public double[] getBounds() 399 { 400 return new double[] {getMinValue(), getMaxValue()}; 401 } 402 403 /** 404 * Return true if this is a compatible java data type (signed integer type only) 405 */ 406 public boolean isJavaType() 407 { 408 return this == getJavaType(); 409 } 410 411 /** 412 * Return true if this is a signed data type 413 */ 414 public boolean isSigned() 415 { 416 return signed; 417 } 418 419 /** 420 * Return true if this is a float data type 421 */ 422 public boolean isFloat() 423 { 424 return !isInteger(); 425 } 426 427 /** 428 * Return true if this is an integer data type 429 */ 430 public boolean isInteger() 431 { 432 return integer; 433 } 434 435 /** 436 * @deprecated Use {@link #getSize()} instead 437 */ 438 @Deprecated 439 public int sizeOf() 440 { 441 return getSize(); 442 } 443 444 /** 445 * Return the size (in byte) of the specified dataType 446 */ 447 public int getSize() 448 { 449 return getBitSize() / 8; 450 } 451 452 /** 453 * Return the size (in bit) of the specified dataType 454 */ 455 public int getBitSize() 456 { 457 return bitSize; 458 } 459 460 /** 461 * Return true if specified data type has same "basic" type (no sign information) data type 462 */ 463 public boolean isSameJavaType(DataType dataType) 464 { 465 return dataType.getJavaType() == getJavaType(); 466 } 467 468 /** 469 * Return the corresponding primitive class type corresponding to this DataType. 470 */ 471 public Class<?> toPrimitiveClass() 472 { 473 return primitiveClass; 474 } 475 476 /** 477 * Return the DataBuffer type corresponding to current DataType 478 */ 479 public int toDataBufferType() 480 { 481 return dataBufferType; 482 } 483 484 /** 485 * Return the PixelType corresponding to current DataType 486 */ 487 public PixelType toPixelType() 488 { 489 return pixelType; 490 } 491 492 /** 493 * Convert DataType to String.<br> 494 * 495 * @param longString 496 * Define if we want long description (bpp information) 497 */ 498 public String toString(boolean longString) 499 { 500 if (longString) 501 return toLongString(); 502 503 return toString(); 504 } 505 506 /** 507 * Convert DataType to long String (long description with bpp information) 508 */ 509 public String toLongString() 510 { 511 return longString; 512 } 513 514 @Override 515 public String toString() 516 { 517 return string; 518 } 519}