HalfFloatArray.st
author Claus Gittinger <cg@exept.de>
Tue, 25 Jun 2019 14:28:51 +0200
changeset 5050 44fa8672d102
parent 5015 c4c87284e2ed
child 5055 f27b17f602ed
permissions -rw-r--r--
#DOCUMENTATION by cg class: SharedQueue comment/format in: #next #nextWithTimeout:

"{ Encoding: utf8 }"

"
 COPYRIGHT (c) 2014 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libbasic2' }"

"{ NameSpace: Smalltalk }"

UnboxedFloatArray variableWordSubclass:#HalfFloatArray
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Collections-Arrayed'
!

!HalfFloatArray primitiveFunctions!
%{
typedef unsigned short uint16;
typedef unsigned int   uint32;
#if 0
#if defined(__GNUC__) || defined(__CLANG__) || defined(__MINGW__)
inline float
XMConvertHalfToFloat(float16_t Value) {
    __m128i V1 = _mm_cvtsi32_si128( (uint32)(Value) );
    __m128 V2 = _mm_cvtph_ps( V1 );
    return _mm_cvtss_f32( V2 );
}

inline float16_t
XMConvertFloatToHalf(float Value) {
    __m128 V1 = _mm_set_ss( Value );
    __m128i V2 = _mm_cvtps_ph( V1, 0 );
    return (float16_t)( _mm_cvtsi128_si32(V2) );
}
#endif
#endif
//
// convert a halffloat (16-bit float) to a float
//
extern float __STX_halffloat_to_float(float16_t h);

//
// convert a float to a halffloat (16-bit float)
//
extern float16_t __STX_float_to_halffloat(float f32);

%}
! !

!HalfFloatArray class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2014 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    HalfFloatArrays store half precision (16bit) floats (and nothing else).
    HalfFloats were traditionally seldom used, but seem to become more popular
    these days, as some 3D graphics accelerators and game engines use them
    for very dense and compact storage of texture and vertex data.

    Notice, that HalfFloats are not supported as first class objects by the ST/X system;
    i.e. outside of a HalfFloatArray, these values are represented as floats
    or doubles. When accessing a HalfFloatArray's element via getters/setters,
    shortFloat (i.e. single precision 32bit floats) are exchanged.

    Be aware that the numeric range of a half-float is very very limited.

    [memory requirements:]
	OBJ-HEADER + (size * 2)

    [See also:]
	FloatArray DoubleArray Array
	http://www.opengl.org/wiki/Small_Float_Formats
	https://en.wikipedia.org/wiki/Half-precision

    [author:]
	Claus Gittinger
"
! !

!HalfFloatArray class methodsFor:'queries'!

elementByteSize
    "for bit-like containers, return the number of bytes stored per element.
     Here, 2 is returned"

    ^ 2
! !

!HalfFloatArray methodsFor:'accessing'!

at:index
%{  /* NOCONTEXT */
    if (__isSmallInteger(index)) {
	int i = __intVal(index);
	int n = __wordArraySize(self);

	if ((unsigned)i <= n) {
	    float16_t h;
	    OBJ newFloat;
	    float f;

	    h = (float16_t)(__WordArrayInstPtr(self)->s_element[i-1]);

	    f = __STX_halffloat_to_float(h);
	    __qMKSFLOAT(newFloat, f);
	    RETURN ( newFloat );
	}
    }
%}.
    self primitiveFailed
!

at:index put:aFloat
%{
    if (! __isImmutable(self)) {
        if (__isSmallInteger(index)) {
            int i = __intVal(index);
            int n = __wordArraySize(self);

            if ((unsigned)i <= n) {
                float16_t h;
                float f;

                if (__isFloat(aFloat)) {
                    f = (float)(__floatVal(aFloat));
                } else if (__isShortFloat(aFloat)) {
                    f = __shortFloatVal(aFloat);
                } else if (__isSmallInteger(aFloat)) {
                    f = (float)(__intVal(aFloat));
                } else
                    goto error;

                h = __STX_float_to_halffloat(f);
                __WordArrayInstPtr(self)->s_element[i-1] = h;
                RETURN (aFloat);
            }
        }
    }
  error: ;
%}.
    "/ arrive here only in case of an error
    self isImmutable ifTrue:[
        self noModificationError
    ].    
    self primitiveFailed

    "Modified: / 09-06-2019 / 15:32:32 / Claus Gittinger"
! !

!HalfFloatArray methodsFor:'queries'!

defaultElement
    ^ ShortFloat zero
!

isValidElement:anObject
    "return true, if I can hold this kind of object"

    ^ anObject isNumber
!

numFloats
    ^ self size
! !

!HalfFloatArray methodsFor:'testing'!

isFloatArray
    "return true if the receiver has float elements.
     These are Float, Double- and HalfFloat arrays"

    ^ true

    "Created: / 02-03-2019 / 23:14:00 / Claus Gittinger"
! !

!HalfFloatArray class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
! !