gov.nasa.worldwind.util.WWBufferUtil Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.util;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.geom.Vec4;
import java.nio.*;
/**
* A collection of useful {@link Buffer} methods, all static.
*
* @author dcollins
* @version $Id: WWBufferUtil.java 1171 2013-02-11 21:45:02Z dcollins $
*/
public class WWBufferUtil
{
/** The size of a short primitive type, in bytes. */
public static final int SIZEOF_SHORT = 2;
/** The size of a int primitive type, in bytes. */
public static final int SIZEOF_INT = 4;
/** The size of a float primitive type, in bytes. */
public static final int SIZEOF_FLOAT = 4;
/** The size of a double primitive type, in bytes. */
public static final int SIZEOF_DOUBLE = 8;
/** The size of a char primitive type, in bytes. */
public static final int SIZEOF_CHAR = 2;
/**
* Allocates a new direct {@link java.nio.ByteBuffer} of the specified size, in chars.
*
* @param size the new ByteBuffer's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new buffer.
*
* @throws IllegalArgumentException if size is negative.
*/
public static ByteBuffer newByteBuffer(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return allocateDirect ? newDirectByteBuffer(size) : ByteBuffer.allocate(size);
}
/**
* Allocates a new direct {@link java.nio.ShortBuffer} of the specified size, in chars.
*
* @param size the new ShortBuffer's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new buffer.
*
* @throws IllegalArgumentException if size is negative.
*/
public static ShortBuffer newShortBuffer(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return allocateDirect ? newDirectByteBuffer(SIZEOF_SHORT * size).asShortBuffer() : ShortBuffer.allocate(size);
}
/**
* Allocates a new direct {@link java.nio.IntBuffer} of the specified size, in chars.
*
* @param size the new IntBuffer's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new buffer.
*
* @throws IllegalArgumentException if size is negative.
*/
public static IntBuffer newIntBuffer(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return allocateDirect ? newDirectByteBuffer(SIZEOF_INT * size).asIntBuffer() : IntBuffer.allocate(size);
}
/**
* Allocates a new direct {@link java.nio.FloatBuffer} of the specified size, in chars.
*
* @param size the new FloatBuffer's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new buffer.
*
* @throws IllegalArgumentException if size is negative.
*/
public static FloatBuffer newFloatBuffer(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return allocateDirect ? newDirectByteBuffer(SIZEOF_FLOAT * size).asFloatBuffer() : FloatBuffer.allocate(size);
}
/**
* Allocates a new direct {@link java.nio.DoubleBuffer} of the specified size, in chars.
*
* @param size the new DoubleBuffer's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new buffer.
*
* @throws IllegalArgumentException if size is negative.
*/
public static DoubleBuffer newDoubleBuffer(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return allocateDirect ? newDirectByteBuffer(SIZEOF_DOUBLE * size).asDoubleBuffer()
: DoubleBuffer.allocate(size);
}
/**
* Allocates a new direct {@link java.nio.CharBuffer} of the specified size, in chars.
*
* @param size the new CharBuffer's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new buffer.
*
* @throws IllegalArgumentException if size is negative.
*/
public static CharBuffer newCharBuffer(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return (allocateDirect ? newDirectByteBuffer(SIZEOF_CHAR * size).asCharBuffer() : CharBuffer.allocate(size));
}
/**
* Allocates a new {@link BufferWrapper} of the specified size, in bytes. The BufferWrapper is backed by a Buffer of
* bytes.
*
* @param size the new BufferWrapper's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new BufferWrapper.
*
* @throws IllegalArgumentException if size is negative.
*/
public static BufferWrapper newByteBufferWrapper(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
ByteBuffer buffer = newByteBuffer(size, allocateDirect);
return new BufferWrapper.ByteBufferWrapper(buffer);
}
/**
* Allocates a new {@link BufferWrapper} of the specified size, in shorts. The BufferWrapper is backed by a Buffer
* of shorts.
*
* @param size the new BufferWrapper's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new BufferWrapper.
*
* @throws IllegalArgumentException if size is negative.
*/
public static BufferWrapper newShortBufferWrapper(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
ShortBuffer buffer = newShortBuffer(size, allocateDirect);
return new BufferWrapper.ShortBufferWrapper(buffer);
}
/**
* Allocates a new {@link BufferWrapper} of the specified size, in ints. The BufferWrapper is backed by a Buffer of
* ints.
*
* @param size the new BufferWrapper's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new BufferWrapper.
*
* @throws IllegalArgumentException if size is negative.
*/
public static BufferWrapper newIntBufferWrapper(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
IntBuffer buffer = newIntBuffer(size, allocateDirect);
return new BufferWrapper.IntBufferWrapper(buffer);
}
/**
* Allocates a new {@link BufferWrapper} of the specified size, in floats. The BufferWrapper is backed by a Buffer
* of floats.
*
* @param size the new BufferWrapper's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new BufferWrapper.
*
* @throws IllegalArgumentException if size is negative.
*/
public static BufferWrapper newFloatBufferWrapper(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
FloatBuffer buffer = newFloatBuffer(size, allocateDirect);
return new BufferWrapper.FloatBufferWrapper(buffer);
}
/**
* Allocates a new {@link BufferWrapper} of the specified size, in doubles. The BufferWrapper is backed by a Buffer
* of doubles.
*
* @param size the new BufferWrapper's size.
* @param allocateDirect true to allocate and return a direct buffer, false to allocate and return a non-direct
* buffer.
*
* @return the new BufferWrapper.
*
* @throws IllegalArgumentException if size is negative.
*/
public static BufferWrapper newDoubleBufferWrapper(int size, boolean allocateDirect)
{
if (size < 0)
{
String message = Logging.getMessage("generic.SizeOutOfRange", size);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
DoubleBuffer buffer = newDoubleBuffer(size, allocateDirect);
return new BufferWrapper.DoubleBufferWrapper(buffer);
}
/**
* Returns a copy of the specified buffer, with the specified new size. The new size must be greater than or equal
* to the specified buffer's size. If the new size is greater than the specified buffer's size, this returns a new
* buffer which is partially filled with the contents of the specified buffer.The returned buffer is a direct
* ByteBuffer if and only if the specified buffer is direct.
*
* @param buffer the buffer to copy.
* @param newSize the new buffer's size, in bytes.
*
* @return the new buffer, with the specified size.
*
* @throws IllegalArgumentException if the buffer is null, if the new size is negative, or if the new size is less
* than the buffer's remaing elements.
*/
public static ByteBuffer copyOf(ByteBuffer buffer, int newSize)
{
if (newSize < 0 || newSize < buffer.remaining())
{
String message = Logging.getMessage("generic.SizeOutOfRange", newSize);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
ByteBuffer newBuffer = newByteBuffer(newSize, buffer.isDirect());
int pos = buffer.position(); // Save the input buffer's current position.
try
{
newBuffer.put(buffer);
newBuffer.rewind();
}
finally
{
buffer.position(pos); // Restore the input buffer's original position.
}
return newBuffer;
}
/**
* Returns a copy of the specified buffer, with the specified new size. The new size must be greater than or equal
* to the specified buffer's size. If the new size is greater than the specified buffer's size, this returns a new
* buffer which is partially filled with the contents of the specified buffer. The returned buffer is a backed by a
* direct ByteBuffer if and only if the specified buffer is direct.
*
* @param buffer the buffer to copy.
* @param newSize the new buffer's size, in chars.
*
* @return the new buffer, with the specified size.
*
* @throws IllegalArgumentException if the buffer is null, if the new size is negative, or if the new size is less
* than the buffer's remaing elements.
*/
public static CharBuffer copyOf(CharBuffer buffer, int newSize)
{
if (newSize < 0 || newSize < buffer.remaining())
{
String message = Logging.getMessage("generic.SizeOutOfRange", newSize);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
CharBuffer newBuffer = newCharBuffer(newSize, buffer.isDirect());
int pos = buffer.position(); // Save the input buffer's current position.
try
{
newBuffer.put(buffer);
newBuffer.rewind();
}
finally
{
buffer.position(pos); // Restore the input buffer's original position.
}
return newBuffer;
}
/**
* Returns a copy of the specified buffer, with the specified new size. The new size must be greater than or equal
* to the specified buffer's size. If the new size is greater than the specified buffer's size, this returns a new
* buffer which is partially filled with the contents of the specified buffer. The returned buffer is a backed by a
* direct ByteBuffer if and only if the specified buffer is direct.
*
* @param buffer the buffer to copy.
* @param newSize the new buffer's size, in shorts.
*
* @return the new buffer, with the specified size.
*
* @throws IllegalArgumentException if the buffer is null, if the new size is negative, or if the new size is less
* than the buffer's remaing elements.
*/
public static ShortBuffer copyOf(ShortBuffer buffer, int newSize)
{
if (newSize < 0 || newSize < buffer.remaining())
{
String message = Logging.getMessage("generic.SizeOutOfRange", newSize);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
ShortBuffer newBuffer = newShortBuffer(newSize, buffer.isDirect());
int pos = buffer.position(); // Save the input buffer's current position.
try
{
newBuffer.put(buffer);
newBuffer.rewind();
}
finally
{
buffer.position(pos); // Restore the input buffer's original position.
}
return newBuffer;
}
/**
* Returns a copy of the specified buffer, with the specified new size. The new size must be greater than or equal
* to the specified buffer's size. If the new size is greater than the specified buffer's size, this returns a new
* buffer which is partially filled with the contents of the specified buffer.The returned buffer is a backed by a
* direct ByteBuffer if and only if the specified buffer is direct.
*
* @param buffer the buffer to copy.
* @param newSize the new buffer's size, in ints.
*
* @return the new buffer, with the specified size.
*
* @throws IllegalArgumentException if the buffer is null, if the new size is negative, or if the new size is less
* than the buffer's remaing elements.
*/
public static IntBuffer copyOf(IntBuffer buffer, int newSize)
{
if (newSize < 0 || newSize < buffer.remaining())
{
String message = Logging.getMessage("generic.SizeOutOfRange", newSize);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
IntBuffer newBuffer = newIntBuffer(newSize, buffer.isDirect());
int pos = buffer.position(); // Save the input buffer's current position.
try
{
newBuffer.put(buffer);
newBuffer.rewind();
}
finally
{
buffer.position(pos); // Restore the input buffer's original position.
}
return newBuffer;
}
/**
* Returns a copy of the specified buffer, with the specified new size. The new size must be greater than or equal
* to the specified buffer's size. If the new size is greater than the specified buffer's size, this returns a new
* buffer which is partially filled with the contents of the specified buffer. The returned buffer is a backed by a
* direct ByteBuffer if and only if the specified buffer is direct.
*
* @param buffer the buffer to copy.
* @param newSize the new buffer's size, in floats.
*
* @return the new buffer, with the specified size.
*
* @throws IllegalArgumentException if the buffer is null, if the new size is negative, or if the new size is less
* than the buffer's remaing elements.
*/
public static FloatBuffer copyOf(FloatBuffer buffer, int newSize)
{
if (newSize < 0 || newSize < buffer.remaining())
{
String message = Logging.getMessage("generic.SizeOutOfRange", newSize);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
FloatBuffer newBuffer = newFloatBuffer(newSize, buffer.isDirect());
int pos = buffer.position(); // Save the input buffer's current position.
try
{
newBuffer.put(buffer);
newBuffer.rewind();
}
finally
{
buffer.position(pos); // Restore the input buffer's original position.
}
return newBuffer;
}
/**
* Returns a copy of the specified buffer, with the specified new size. The new size must be greater than or equal
* to the specified buffer's size. If the new size is greater than the specified buffer's size, this returns a new
* buffer which is partially filled with the contents of the specified buffer. The returned buffer is a backed by a
* direct ByteBuffer if and only if the specified buffer is direct.
*
* @param buffer the buffer to copy.
* @param newSize the new buffer's size, in doubles.
*
* @return the new buffer, with the specified size.
*
* @throws IllegalArgumentException if the buffer is null, if the new size is negative, or if the new size is less
* than the buffer's remaing elements.
*/
public static DoubleBuffer copyOf(DoubleBuffer buffer, int newSize)
{
if (newSize < 0 || newSize < buffer.remaining())
{
String message = Logging.getMessage("generic.SizeOutOfRange", newSize);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
DoubleBuffer newBuffer = newDoubleBuffer(newSize, buffer.isDirect());
int pos = buffer.position(); // Save the input buffer's current position.
try
{
newBuffer.put(buffer);
newBuffer.rewind();
}
finally
{
buffer.position(pos); // Restore the input buffer's original position.
}
return newBuffer;
}
/**
* Returns the size in bytes of the specified primitive data type, or -1 if the specified type is unrecognized.
* Recognized primitive types are as follows: - {@link gov.nasa.worldwind.avlist.AVKey#INT8}
- {@link
* gov.nasa.worldwind.avlist.AVKey#INT16}
- {@link gov.nasa.worldwind.avlist.AVKey#INT32}
- {@link
* gov.nasa.worldwind.avlist.AVKey#FLOAT32}
- {@link gov.nasa.worldwind.avlist.AVKey#FLOAT64}
*
* @param dataType the primitive data type.
*
* @return the size of the primitive data type, in bytes.
*
* @throws IllegalArgumentException if the data type is null.
*/
public static int sizeOfPrimitiveType(Object dataType)
{
if (dataType == null)
{
String message = Logging.getMessage("nullValue.DataTypeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (AVKey.INT8.equals(dataType))
return 1;
else if (AVKey.INT16.equals(dataType))
return SIZEOF_SHORT;
else if (AVKey.INT32.equals(dataType))
return SIZEOF_INT;
else if (AVKey.FLOAT32.equals(dataType))
return SIZEOF_FLOAT;
else if (AVKey.FLOAT64.equals(dataType))
return SIZEOF_DOUBLE;
return -1;
}
/**
* Returns the minimum and maximum floating point values in the specified buffer. Values equivalent to the specified
* missingDataSignal
are ignored. This returns null if the buffer is empty or contains only missing
* values.
*
* @param buffer the buffer to search for the minimum and maximum values.
* @param missingDataSignal the number indicating a specific floating point value to ignore.
*
* @return an array containing the minimum value in index 0 and the maximum value in index 1, or null if the buffer
* is empty or contains only missing values.
*
* @throws IllegalArgumentException if the buffer is null.
*/
public static double[] computeExtremeValues(BufferWrapper buffer, double missingDataSignal)
{
if (buffer == null)
{
String message = Logging.getMessage("nullValue.BufferIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
double min = Double.MAX_VALUE;
double max = -Double.MAX_VALUE;
for (int i = 0; i < buffer.length(); i++)
{
double value = buffer.getDouble(i);
if (Double.compare(value, missingDataSignal) == 0)
continue;
if (min > value)
min = value;
if (max < value)
max = value;
}
if (Double.compare(min, Double.MAX_VALUE) == 0 || Double.compare(max, -Double.MAX_VALUE) == 0)
return null;
return new double[] {min, max};
}
/**
* Returns the minimum and maximum floating point values in the specified buffer. Values equivalent to
* Double.NaN
are ignored. This returns null if the buffer is empty or contains only NaN values.
*
* @param buffer the buffer to search for the minimum and maximum values.
*
* @return an array containing the minimum value in index 0 and the maximum value in index 1, or null if the buffer
* is empty or contains only NaN values.
*
* @throws IllegalArgumentException if the buffer is null.
*/
public static double[] computeExtremeValues(BufferWrapper buffer)
{
if (buffer == null)
{
String message = Logging.getMessage("nullValue.BufferIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return computeExtremeValues(buffer, Double.NaN);
}
protected static ByteBuffer newDirectByteBuffer(int size)
{
return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
}
/**
* Copies a specified array of vertices to a specified vertex buffer. This method calls {@link
* java.nio.FloatBuffer#flip()} prior to returning.
*
* @param array the vertices to copy.
* @param buffer the buffer to copy the vertices to. Must have enough remaining space to hold the vertices.
*
* @return the buffer specified as input, with its limit incremented by the number of vertices copied, and its
* position set to 0.
*/
public static FloatBuffer copyArrayToBuffer(Vec4[] array, FloatBuffer buffer)
{
if (array == null)
{
String message = Logging.getMessage("nullValue.ArrayIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (buffer == null)
{
String message = Logging.getMessage("nullValue.BufferIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
for (Vec4 v : array)
{
buffer.put((float) v.x).put((float) v.y).put((float) v.z);
}
buffer.flip(); // sets the limit to the position and then the position to 0.
return buffer;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy