EXRLoader: formatting

上级 8b79ce8b
......@@ -745,7 +745,7 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
var count = - l;
size -= count + 1;
for ( var i = 0; i < count; i ++ ) {
out.push( reader.getUint8( p ++ ) );
......@@ -757,7 +757,7 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
var count = l;
size -= 2;
var value = reader.getUint8( p ++ );
for ( var i = 0; i < count + 1; i ++ ) {
......@@ -788,7 +788,7 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
var numBlocksY = Math.ceil( height / 8.0 );
var leftoverX = width - ( numBlocksX - 1 ) * 8;
var leftoverY = height - ( numBlocksY - 1 ) * 8;
var currAcComp = { value: 0 };
var currDcComp = new Array( numComp );
var dctData = new Array( numComp );
......@@ -825,7 +825,7 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
halfZigBlock[ comp ].fill( 0 );
// set block DC component
halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ]++ ];
halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ] ++ ];
// set block AC components
unRleAC( currAcComp, acBuffer, halfZigBlock[ comp ] );
......@@ -857,13 +857,13 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
let type = channelData[ cscSet.idx[ comp ] ].type;
for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) {
offset = rowOffsets[ comp ][ y ];
for ( let blockx = 0; blockx < numFullBlocksX; ++ blockx ) {
let src = blockx * 64 + ( ( y & 0x7 ) * 8 );
dataView.setUint16( offset + 0 * INT16_SIZE * type, rowBlock[ comp ][ src + 0 ], true );
dataView.setUint16( offset + 1 * INT16_SIZE * type, rowBlock[ comp ][ src + 1 ], true );
dataView.setUint16( offset + 2 * INT16_SIZE * type, rowBlock[ comp ][ src + 2 ], true );
......@@ -875,29 +875,29 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
dataView.setUint16( offset + 7 * INT16_SIZE * type, rowBlock[ comp ][ src + 7 ], true );
offset += 8 * INT16_SIZE * type;
}
}
// handle partial X blocks
if ( numFullBlocksX != numBlocksX ) {
for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) {
let offset = rowOffsets[ comp ][ y ] + 8 * numFullBlocksX * INT16_SIZE * type;
let src = numFullBlocksX * 64 + ( ( y & 0x7 ) * 8 );
for ( let x = 0; x < maxX; ++ x ) {
dataView.setUint16( offset + x * INT16_SIZE * type, rowBlock[ comp ][ src + x ], true );
}
}
}
} // comp
} // blocky
......@@ -955,11 +955,11 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
} else {
halfZigBlock[ dctComp ] = acValue;
dctComp++;
dctComp ++;
}
currAcComp.value++;
currAcComp.value ++;
}
......@@ -967,88 +967,88 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
function unZigZag( src, dst ) {
dst[0] = decodeFloat16( src[0] );
dst[1] = decodeFloat16( src[1] );
dst[2] = decodeFloat16( src[5] );
dst[3] = decodeFloat16( src[6] );
dst[4] = decodeFloat16( src[14] );
dst[5] = decodeFloat16( src[15] );
dst[6] = decodeFloat16( src[27] );
dst[7] = decodeFloat16( src[28] );
dst[8] = decodeFloat16( src[2] );
dst[9] = decodeFloat16( src[4] );
dst[10] = decodeFloat16( src[7] );
dst[11] = decodeFloat16( src[13] );
dst[12] = decodeFloat16( src[16] );
dst[13] = decodeFloat16( src[26] );
dst[14] = decodeFloat16( src[29] );
dst[15] = decodeFloat16( src[42] );
dst[16] = decodeFloat16( src[3] );
dst[17] = decodeFloat16( src[8] );
dst[18] = decodeFloat16( src[12] );
dst[19] = decodeFloat16( src[17] );
dst[20] = decodeFloat16( src[25] );
dst[21] = decodeFloat16( src[30] );
dst[22] = decodeFloat16( src[41] );
dst[23] = decodeFloat16( src[43] );
dst[24] = decodeFloat16( src[9] );
dst[25] = decodeFloat16( src[11] );
dst[26] = decodeFloat16( src[18] );
dst[27] = decodeFloat16( src[24] );
dst[28] = decodeFloat16( src[31] );
dst[29] = decodeFloat16( src[40] );
dst[30] = decodeFloat16( src[44] );
dst[31] = decodeFloat16( src[53] );
dst[32] = decodeFloat16( src[10] );
dst[33] = decodeFloat16( src[19] );
dst[34] = decodeFloat16( src[23] );
dst[35] = decodeFloat16( src[32] );
dst[36] = decodeFloat16( src[39] );
dst[37] = decodeFloat16( src[45] );
dst[38] = decodeFloat16( src[52] );
dst[39] = decodeFloat16( src[54] );
dst[40] = decodeFloat16( src[20] );
dst[41] = decodeFloat16( src[22] );
dst[42] = decodeFloat16( src[33] );
dst[43] = decodeFloat16( src[38] );
dst[44] = decodeFloat16( src[46] );
dst[45] = decodeFloat16( src[51] );
dst[46] = decodeFloat16( src[55] );
dst[47] = decodeFloat16( src[60] );
dst[48] = decodeFloat16( src[21] );
dst[49] = decodeFloat16( src[34] );
dst[50] = decodeFloat16( src[37] );
dst[51] = decodeFloat16( src[47] );
dst[52] = decodeFloat16( src[50] );
dst[53] = decodeFloat16( src[56] );
dst[54] = decodeFloat16( src[59] );
dst[55] = decodeFloat16( src[61] );
dst[56] = decodeFloat16( src[35] );
dst[57] = decodeFloat16( src[36] );
dst[58] = decodeFloat16( src[48] );
dst[59] = decodeFloat16( src[49] );
dst[60] = decodeFloat16( src[57] );
dst[61] = decodeFloat16( src[58] );
dst[62] = decodeFloat16( src[62] );
dst[63] = decodeFloat16( src[63] );
dst[ 0 ] = decodeFloat16( src[ 0 ] );
dst[ 1 ] = decodeFloat16( src[ 1 ] );
dst[ 2 ] = decodeFloat16( src[ 5 ] );
dst[ 3 ] = decodeFloat16( src[ 6 ] );
dst[ 4 ] = decodeFloat16( src[ 14 ] );
dst[ 5 ] = decodeFloat16( src[ 15 ] );
dst[ 6 ] = decodeFloat16( src[ 27 ] );
dst[ 7 ] = decodeFloat16( src[ 28 ] );
dst[ 8 ] = decodeFloat16( src[ 2 ] );
dst[ 9 ] = decodeFloat16( src[ 4 ] );
dst[ 10 ] = decodeFloat16( src[ 7 ] );
dst[ 11 ] = decodeFloat16( src[ 13 ] );
dst[ 12 ] = decodeFloat16( src[ 16 ] );
dst[ 13 ] = decodeFloat16( src[ 26 ] );
dst[ 14 ] = decodeFloat16( src[ 29 ] );
dst[ 15 ] = decodeFloat16( src[ 42 ] );
dst[ 16 ] = decodeFloat16( src[ 3 ] );
dst[ 17 ] = decodeFloat16( src[ 8 ] );
dst[ 18 ] = decodeFloat16( src[ 12 ] );
dst[ 19 ] = decodeFloat16( src[ 17 ] );
dst[ 20 ] = decodeFloat16( src[ 25 ] );
dst[ 21 ] = decodeFloat16( src[ 30 ] );
dst[ 22 ] = decodeFloat16( src[ 41 ] );
dst[ 23 ] = decodeFloat16( src[ 43 ] );
dst[ 24 ] = decodeFloat16( src[ 9 ] );
dst[ 25 ] = decodeFloat16( src[ 11 ] );
dst[ 26 ] = decodeFloat16( src[ 18 ] );
dst[ 27 ] = decodeFloat16( src[ 24 ] );
dst[ 28 ] = decodeFloat16( src[ 31 ] );
dst[ 29 ] = decodeFloat16( src[ 40 ] );
dst[ 30 ] = decodeFloat16( src[ 44 ] );
dst[ 31 ] = decodeFloat16( src[ 53 ] );
dst[ 32 ] = decodeFloat16( src[ 10 ] );
dst[ 33 ] = decodeFloat16( src[ 19 ] );
dst[ 34 ] = decodeFloat16( src[ 23 ] );
dst[ 35 ] = decodeFloat16( src[ 32 ] );
dst[ 36 ] = decodeFloat16( src[ 39 ] );
dst[ 37 ] = decodeFloat16( src[ 45 ] );
dst[ 38 ] = decodeFloat16( src[ 52 ] );
dst[ 39 ] = decodeFloat16( src[ 54 ] );
dst[ 40 ] = decodeFloat16( src[ 20 ] );
dst[ 41 ] = decodeFloat16( src[ 22 ] );
dst[ 42 ] = decodeFloat16( src[ 33 ] );
dst[ 43 ] = decodeFloat16( src[ 38 ] );
dst[ 44 ] = decodeFloat16( src[ 46 ] );
dst[ 45 ] = decodeFloat16( src[ 51 ] );
dst[ 46 ] = decodeFloat16( src[ 55 ] );
dst[ 47 ] = decodeFloat16( src[ 60 ] );
dst[ 48 ] = decodeFloat16( src[ 21 ] );
dst[ 49 ] = decodeFloat16( src[ 34 ] );
dst[ 50 ] = decodeFloat16( src[ 37 ] );
dst[ 51 ] = decodeFloat16( src[ 47 ] );
dst[ 52 ] = decodeFloat16( src[ 50 ] );
dst[ 53 ] = decodeFloat16( src[ 56 ] );
dst[ 54 ] = decodeFloat16( src[ 59 ] );
dst[ 55 ] = decodeFloat16( src[ 61 ] );
dst[ 56 ] = decodeFloat16( src[ 35 ] );
dst[ 57 ] = decodeFloat16( src[ 36 ] );
dst[ 58 ] = decodeFloat16( src[ 48 ] );
dst[ 59 ] = decodeFloat16( src[ 49 ] );
dst[ 60 ] = decodeFloat16( src[ 57 ] );
dst[ 61 ] = decodeFloat16( src[ 58 ] );
dst[ 62 ] = decodeFloat16( src[ 62 ] );
dst[ 63 ] = decodeFloat16( src[ 63 ] );
}
function dctInverse( data ) {
const a = .5 * Math.cos ( 3.14159 / 4.0 );
const b = .5 * Math.cos ( 3.14159 / 16.0 );
const c = .5 * Math.cos ( 3.14159 / 8.0 );
const d = .5 * Math.cos ( 3.*3.14159 / 16.0 );
const e = .5 * Math.cos ( 5.*3.14159 / 16.0 );
const f = .5 * Math.cos ( 3.*3.14159 / 8.0 );
const g = .5 * Math.cos ( 7.*3.14159 / 16.0 );
const a = 0.5 * Math.cos( 3.14159 / 4.0 );
const b = 0.5 * Math.cos( 3.14159 / 16.0 );
const c = 0.5 * Math.cos( 3.14159 / 8.0 );
const d = 0.5 * Math.cos( 3.0 * 3.14159 / 16.0 );
const e = 0.5 * Math.cos( 5.0 * 3.14159 / 16.0 );
const f = 0.5 * Math.cos( 3.0 * 3.14159 / 8.0 );
const g = 0.5 * Math.cos( 7.0 * 3.14159 / 16.0 );
var alpha = new Array( 4 );
var beta = new Array( 4 );
......@@ -1059,31 +1059,31 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
var rowPtr = row * 8;
alpha[ 0 ] = c * data[ rowPtr + 2 ];
alpha[ 1 ] = f * data[ rowPtr + 2 ];
alpha[ 2 ] = c * data[ rowPtr + 6 ];
alpha[ 3 ] = f * data[ rowPtr + 6 ];
alpha[ 0 ] = c * data[ rowPtr + 2 ];
alpha[ 1 ] = f * data[ rowPtr + 2 ];
alpha[ 2 ] = c * data[ rowPtr + 6 ];
alpha[ 3 ] = f * data[ rowPtr + 6 ];
beta[ 0 ] = b * data[ rowPtr + 1 ] + d * data[ rowPtr + 3 ] + e * data[ rowPtr + 5 ] + g * data[ rowPtr + 7 ];
beta[ 1 ] = d * data[ rowPtr + 1 ] - g * data[ rowPtr + 3 ] - b * data[ rowPtr + 5 ] - e * data[ rowPtr + 7 ];
beta[ 2 ] = e * data[ rowPtr + 1 ] - b * data[ rowPtr + 3 ] + g * data[ rowPtr + 5 ] + d * data[ rowPtr + 7 ];
beta[ 3 ] = g * data[ rowPtr + 1 ] - e * data[ rowPtr + 3 ] + d * data[ rowPtr + 5 ] - b * data[ rowPtr + 7 ];
theta[ 0 ] = a * ( data[ rowPtr + 0 ] + data[ rowPtr + 4 ] );
theta[ 3 ] = a * ( data[ rowPtr + 0 ] - data[ rowPtr + 4 ] );
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
gamma[ 0 ] = theta[ 0 ] + theta[ 1 ];
gamma[ 1 ] = theta[ 3 ] + theta[ 2 ];
gamma[ 2 ] = theta[ 3 ] - theta[ 2 ];
gamma[ 3 ] = theta[ 0 ] - theta[ 1 ];
data[ rowPtr + 0 ] = gamma[ 0 ] + beta[ 0 ];
data[ rowPtr + 1 ] = gamma[ 1 ] + beta[ 1 ];
data[ rowPtr + 2 ] = gamma[ 2 ] + beta[ 2 ];
data[ rowPtr + 3 ] = gamma[ 3 ] + beta[ 3 ];
data[ rowPtr + 4 ] = gamma[ 3 ] - beta[ 3 ];
data[ rowPtr + 5 ] = gamma[ 2 ] - beta[ 2 ];
data[ rowPtr + 6 ] = gamma[ 1 ] - beta[ 1 ];
......@@ -1093,29 +1093,29 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
for ( var column = 0; column < 8; ++ column ) {
alpha[ 0 ] = c * data[ 16 + column ];
alpha[ 1 ] = f * data[ 16 + column ];
alpha[ 2 ] = c * data[ 48 + column ];
alpha[ 3 ] = f * data[ 48 + column ];
alpha[ 0 ] = c * data[ 16 + column ];
alpha[ 1 ] = f * data[ 16 + column ];
alpha[ 2 ] = c * data[ 48 + column ];
alpha[ 3 ] = f * data[ 48 + column ];
beta[ 0 ] = b * data[ 8 + column ] + d * data[ 24 + column ] + e * data[ 40 + column ] + g * data[ 56 + column ];
beta[ 1 ] = d * data[ 8 + column ] - g * data[ 24 + column ] - b * data[ 40 + column ] - e * data[ 56 + column ];
beta[ 2 ] = e * data[ 8 + column ] - b * data[ 24 + column ] + g * data[ 40 + column ] + d * data[ 56 + column ];
beta[ 3 ] = g * data [8 + column ] - e * data[ 24 + column ] + d * data[ 40 + column ] - b * data[ 56 + column ];
beta[ 0 ] = b * data[ 8 + column ] + d * data[ 24 + column ] + e * data[ 40 + column ] + g * data[ 56 + column ];
beta[ 1 ] = d * data[ 8 + column ] - g * data[ 24 + column ] - b * data[ 40 + column ] - e * data[ 56 + column ];
beta[ 2 ] = e * data[ 8 + column ] - b * data[ 24 + column ] + g * data[ 40 + column ] + d * data[ 56 + column ];
beta[ 3 ] = g * data[ 8 + column ] - e * data[ 24 + column ] + d * data[ 40 + column ] - b * data[ 56 + column ];
theta[ 0 ] = a * ( data[ column ] + data[ 32 + column ] );
theta[ 3 ] = a * ( data[ column ] - data[ 32 + column ] );
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
gamma[ 0 ] = theta[ 0 ] + theta[ 1 ];
gamma[ 1 ] = theta[ 3 ] + theta[ 2 ];
gamma[ 2 ] = theta[ 3 ] - theta[ 2 ];
gamma[ 3 ] = theta[ 0 ] - theta[ 1 ];
data[ column ] = gamma[ 0 ] + beta[ 0 ];
data[ 8 + column ] = gamma[ 1 ] + beta[ 1 ];
data[ 0 + column ] = gamma[ 0 ] + beta[ 0 ];
data[ 8 + column ] = gamma[ 1 ] + beta[ 1 ];
data[ 16 + column ] = gamma[ 2 ] + beta[ 2 ];
data[ 24 + column ] = gamma[ 3 ] + beta[ 3 ];
......@@ -1334,15 +1334,15 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
totalDcUncompressedCount: parseInt64( inDataView, inOffset ),
acCompression: parseInt64( inDataView, inOffset )
}
};
if ( dwaHeader.version < 2 )
if ( dwaHeader.version < 2 )
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported';
// Read channel ruleset information
var channelRules = new Array();
var ruleSize = parseUint16( inDataView, inOffset ) - INT16_SIZE;
while ( ruleSize > 0 ) {
var name = parseNullTerminatedString( inDataView.buffer, inOffset );
......@@ -1352,10 +1352,10 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
var index = new Int8Array( [ csc ] )[ 0 ];
var type = parseUint8( inDataView, inOffset );
channelRules.push( {
name: name,
index: index,
type: type,
channelRules.push( {
name: name,
index: index,
type: type,
compression: compression,
} );
......@@ -1443,7 +1443,7 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
array: info.array,
offset: inOffset,
size: dwaHeader.dcCompressedSize
}
};
var dcBuffer = new Uint16Array( uncompressZIP( zlibInfo ).buffer );
inOffset.value += dwaHeader.dcCompressedSize;
......@@ -1505,20 +1505,22 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
for ( var byte = 0; byte < INT16_SIZE * cd.type; ++ byte ) {
outBuffer[ rowOffsetBytes++ ] = rleBuffer[ rleOffset + byte * cd.width * cd.height ];
outBuffer[ rowOffsetBytes ++ ] = rleBuffer[ rleOffset + byte * cd.width * cd.height ];
}
rleOffset++
rleOffset ++;
}
row++;
row ++;
}
break;
case LOSSY_DCT: // skip
default:
throw 'EXRLoader.parse: unsupported channel compression';
......@@ -1641,45 +1643,60 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
}
// https://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript
var encodeFloat16 = ( function() {
var floatView = new Float32Array(1);
var int32View = new Int32Array(floatView.buffer);
return function toHalf( fval ) {
floatView[ 0 ] = fval;
var fbits = int32View[ 0 ];
var sign = ( fbits >> 16 ) & 0x8000; // sign only
var val = ( fbits & 0x7fffffff ) + 0x1000; // rounded value
if ( val >= 0x47800000 ) { // might be or become NaN/Inf
if ( ( fbits & 0x7fffffff ) >= 0x47800000 ) {
// is or must become NaN/Inf
if( val < 0x7f800000 ) { // was value but too large
return sign | 0x7c00; // make it +/-Inf
}
return sign | 0x7c00 | // remains +/-Inf or NaN
( fbits & 0x007fffff ) >> 13; // keep NaN (and Inf) bits
var encodeFloat16 = ( function () {
// Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
var floatView = new Float32Array( 1 );
var int32View = new Int32Array( floatView.buffer );
/* This method is faster than the OpenEXR implementation (very often
* used, eg. in Ogre), with the additional benefit of rounding, inspired
* by James Tursa?s half-precision code. */
return function toHalf( val ) {
floatView[ 0 ] = val;
var x = int32View[ 0 ];
var bits = ( x >> 16 ) & 0x8000; /* Get the sign */
var m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */
var e = ( x >> 23 ) & 0xff; /* Using int is faster here */
/* If zero, or denormal, or exponent underflows too much for a denormal
* half, return signed zero. */
if ( e < 103 ) return bits;
/* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
if ( e > 142 ) {
bits |= 0x7c00;
/* If exponent was 0xff and one mantissa bit was set, it means NaN,
* not Inf, so make sure we set one mantissa bit too. */
bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff );
return bits;
}
/* If exponent underflows but not too much, return a denormal */
if ( e < 113 ) {
m |= 0x0800;
/* Extra rounding may overflow and set mantissa to 0 and exponent
* to 1, which is OK. */
bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 );
return bits;
}
return sign | 0x7bff; // unrounded not quite Inf
}
if ( val >= 0x38800000 ) { // remains normalized value
return sign | val - 0x38000000 >> 13; // exp - 127 + 15
}
if ( val < 0x33000000 ) { // too small for subnormal
return sign; // becomes +/-0
}
val = ( fbits & 0x7fffffff ) >> 23; // tmp exp for subnormal calc
return sign | ( ( fbits & 0x7fffff | 0x800000 ) // add subnormal bit
+ ( 0x800000 >>> val - 102 ) // round depending on cut off
>> 126 - val ); // div by 2^(1-(exp-127+15)) and >> 13 | exp=
bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 );
/* Extra rounding. An overflow will set mantissa to 0 and increment
* the exponent, which is OK. */
bits += m & 1;
return bits;
};
} () );
} )();
function parseUint16( dataView, offset ) {
......@@ -1925,7 +1942,7 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
scanlineBlockSize = 256;
uncompress = uncompressDWA;
break;
default:
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported';
......
......@@ -756,7 +756,7 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
var count = - l;
size -= count + 1;
for ( var i = 0; i < count; i ++ ) {
out.push( reader.getUint8( p ++ ) );
......@@ -768,7 +768,7 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
var count = l;
size -= 2;
var value = reader.getUint8( p ++ );
for ( var i = 0; i < count + 1; i ++ ) {
......@@ -799,7 +799,7 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
var numBlocksY = Math.ceil( height / 8.0 );
var leftoverX = width - ( numBlocksX - 1 ) * 8;
var leftoverY = height - ( numBlocksY - 1 ) * 8;
var currAcComp = { value: 0 };
var currDcComp = new Array( numComp );
var dctData = new Array( numComp );
......@@ -836,7 +836,7 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
halfZigBlock[ comp ].fill( 0 );
// set block DC component
halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ]++ ];
halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ] ++ ];
// set block AC components
unRleAC( currAcComp, acBuffer, halfZigBlock[ comp ] );
......@@ -868,13 +868,13 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
let type = channelData[ cscSet.idx[ comp ] ].type;
for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) {
offset = rowOffsets[ comp ][ y ];
for ( let blockx = 0; blockx < numFullBlocksX; ++ blockx ) {
let src = blockx * 64 + ( ( y & 0x7 ) * 8 );
dataView.setUint16( offset + 0 * INT16_SIZE * type, rowBlock[ comp ][ src + 0 ], true );
dataView.setUint16( offset + 1 * INT16_SIZE * type, rowBlock[ comp ][ src + 1 ], true );
dataView.setUint16( offset + 2 * INT16_SIZE * type, rowBlock[ comp ][ src + 2 ], true );
......@@ -886,29 +886,29 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
dataView.setUint16( offset + 7 * INT16_SIZE * type, rowBlock[ comp ][ src + 7 ], true );
offset += 8 * INT16_SIZE * type;
}
}
// handle partial X blocks
if ( numFullBlocksX != numBlocksX ) {
for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) {
let offset = rowOffsets[ comp ][ y ] + 8 * numFullBlocksX * INT16_SIZE * type;
let src = numFullBlocksX * 64 + ( ( y & 0x7 ) * 8 );
for ( let x = 0; x < maxX; ++ x ) {
dataView.setUint16( offset + x * INT16_SIZE * type, rowBlock[ comp ][ src + x ], true );
}
}
}
} // comp
} // blocky
......@@ -966,11 +966,11 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
} else {
halfZigBlock[ dctComp ] = acValue;
dctComp++;
dctComp ++;
}
currAcComp.value++;
currAcComp.value ++;
}
......@@ -978,88 +978,88 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
function unZigZag( src, dst ) {
dst[0] = decodeFloat16( src[0] );
dst[1] = decodeFloat16( src[1] );
dst[2] = decodeFloat16( src[5] );
dst[3] = decodeFloat16( src[6] );
dst[4] = decodeFloat16( src[14] );
dst[5] = decodeFloat16( src[15] );
dst[6] = decodeFloat16( src[27] );
dst[7] = decodeFloat16( src[28] );
dst[8] = decodeFloat16( src[2] );
dst[9] = decodeFloat16( src[4] );
dst[10] = decodeFloat16( src[7] );
dst[11] = decodeFloat16( src[13] );
dst[12] = decodeFloat16( src[16] );
dst[13] = decodeFloat16( src[26] );
dst[14] = decodeFloat16( src[29] );
dst[15] = decodeFloat16( src[42] );
dst[16] = decodeFloat16( src[3] );
dst[17] = decodeFloat16( src[8] );
dst[18] = decodeFloat16( src[12] );
dst[19] = decodeFloat16( src[17] );
dst[20] = decodeFloat16( src[25] );
dst[21] = decodeFloat16( src[30] );
dst[22] = decodeFloat16( src[41] );
dst[23] = decodeFloat16( src[43] );
dst[24] = decodeFloat16( src[9] );
dst[25] = decodeFloat16( src[11] );
dst[26] = decodeFloat16( src[18] );
dst[27] = decodeFloat16( src[24] );
dst[28] = decodeFloat16( src[31] );
dst[29] = decodeFloat16( src[40] );
dst[30] = decodeFloat16( src[44] );
dst[31] = decodeFloat16( src[53] );
dst[32] = decodeFloat16( src[10] );
dst[33] = decodeFloat16( src[19] );
dst[34] = decodeFloat16( src[23] );
dst[35] = decodeFloat16( src[32] );
dst[36] = decodeFloat16( src[39] );
dst[37] = decodeFloat16( src[45] );
dst[38] = decodeFloat16( src[52] );
dst[39] = decodeFloat16( src[54] );
dst[40] = decodeFloat16( src[20] );
dst[41] = decodeFloat16( src[22] );
dst[42] = decodeFloat16( src[33] );
dst[43] = decodeFloat16( src[38] );
dst[44] = decodeFloat16( src[46] );
dst[45] = decodeFloat16( src[51] );
dst[46] = decodeFloat16( src[55] );
dst[47] = decodeFloat16( src[60] );
dst[48] = decodeFloat16( src[21] );
dst[49] = decodeFloat16( src[34] );
dst[50] = decodeFloat16( src[37] );
dst[51] = decodeFloat16( src[47] );
dst[52] = decodeFloat16( src[50] );
dst[53] = decodeFloat16( src[56] );
dst[54] = decodeFloat16( src[59] );
dst[55] = decodeFloat16( src[61] );
dst[56] = decodeFloat16( src[35] );
dst[57] = decodeFloat16( src[36] );
dst[58] = decodeFloat16( src[48] );
dst[59] = decodeFloat16( src[49] );
dst[60] = decodeFloat16( src[57] );
dst[61] = decodeFloat16( src[58] );
dst[62] = decodeFloat16( src[62] );
dst[63] = decodeFloat16( src[63] );
dst[ 0 ] = decodeFloat16( src[ 0 ] );
dst[ 1 ] = decodeFloat16( src[ 1 ] );
dst[ 2 ] = decodeFloat16( src[ 5 ] );
dst[ 3 ] = decodeFloat16( src[ 6 ] );
dst[ 4 ] = decodeFloat16( src[ 14 ] );
dst[ 5 ] = decodeFloat16( src[ 15 ] );
dst[ 6 ] = decodeFloat16( src[ 27 ] );
dst[ 7 ] = decodeFloat16( src[ 28 ] );
dst[ 8 ] = decodeFloat16( src[ 2 ] );
dst[ 9 ] = decodeFloat16( src[ 4 ] );
dst[ 10 ] = decodeFloat16( src[ 7 ] );
dst[ 11 ] = decodeFloat16( src[ 13 ] );
dst[ 12 ] = decodeFloat16( src[ 16 ] );
dst[ 13 ] = decodeFloat16( src[ 26 ] );
dst[ 14 ] = decodeFloat16( src[ 29 ] );
dst[ 15 ] = decodeFloat16( src[ 42 ] );
dst[ 16 ] = decodeFloat16( src[ 3 ] );
dst[ 17 ] = decodeFloat16( src[ 8 ] );
dst[ 18 ] = decodeFloat16( src[ 12 ] );
dst[ 19 ] = decodeFloat16( src[ 17 ] );
dst[ 20 ] = decodeFloat16( src[ 25 ] );
dst[ 21 ] = decodeFloat16( src[ 30 ] );
dst[ 22 ] = decodeFloat16( src[ 41 ] );
dst[ 23 ] = decodeFloat16( src[ 43 ] );
dst[ 24 ] = decodeFloat16( src[ 9 ] );
dst[ 25 ] = decodeFloat16( src[ 11 ] );
dst[ 26 ] = decodeFloat16( src[ 18 ] );
dst[ 27 ] = decodeFloat16( src[ 24 ] );
dst[ 28 ] = decodeFloat16( src[ 31 ] );
dst[ 29 ] = decodeFloat16( src[ 40 ] );
dst[ 30 ] = decodeFloat16( src[ 44 ] );
dst[ 31 ] = decodeFloat16( src[ 53 ] );
dst[ 32 ] = decodeFloat16( src[ 10 ] );
dst[ 33 ] = decodeFloat16( src[ 19 ] );
dst[ 34 ] = decodeFloat16( src[ 23 ] );
dst[ 35 ] = decodeFloat16( src[ 32 ] );
dst[ 36 ] = decodeFloat16( src[ 39 ] );
dst[ 37 ] = decodeFloat16( src[ 45 ] );
dst[ 38 ] = decodeFloat16( src[ 52 ] );
dst[ 39 ] = decodeFloat16( src[ 54 ] );
dst[ 40 ] = decodeFloat16( src[ 20 ] );
dst[ 41 ] = decodeFloat16( src[ 22 ] );
dst[ 42 ] = decodeFloat16( src[ 33 ] );
dst[ 43 ] = decodeFloat16( src[ 38 ] );
dst[ 44 ] = decodeFloat16( src[ 46 ] );
dst[ 45 ] = decodeFloat16( src[ 51 ] );
dst[ 46 ] = decodeFloat16( src[ 55 ] );
dst[ 47 ] = decodeFloat16( src[ 60 ] );
dst[ 48 ] = decodeFloat16( src[ 21 ] );
dst[ 49 ] = decodeFloat16( src[ 34 ] );
dst[ 50 ] = decodeFloat16( src[ 37 ] );
dst[ 51 ] = decodeFloat16( src[ 47 ] );
dst[ 52 ] = decodeFloat16( src[ 50 ] );
dst[ 53 ] = decodeFloat16( src[ 56 ] );
dst[ 54 ] = decodeFloat16( src[ 59 ] );
dst[ 55 ] = decodeFloat16( src[ 61 ] );
dst[ 56 ] = decodeFloat16( src[ 35 ] );
dst[ 57 ] = decodeFloat16( src[ 36 ] );
dst[ 58 ] = decodeFloat16( src[ 48 ] );
dst[ 59 ] = decodeFloat16( src[ 49 ] );
dst[ 60 ] = decodeFloat16( src[ 57 ] );
dst[ 61 ] = decodeFloat16( src[ 58 ] );
dst[ 62 ] = decodeFloat16( src[ 62 ] );
dst[ 63 ] = decodeFloat16( src[ 63 ] );
}
function dctInverse( data ) {
const a = .5 * Math.cos ( 3.14159 / 4.0 );
const b = .5 * Math.cos ( 3.14159 / 16.0 );
const c = .5 * Math.cos ( 3.14159 / 8.0 );
const d = .5 * Math.cos ( 3.*3.14159 / 16.0 );
const e = .5 * Math.cos ( 5.*3.14159 / 16.0 );
const f = .5 * Math.cos ( 3.*3.14159 / 8.0 );
const g = .5 * Math.cos ( 7.*3.14159 / 16.0 );
const a = 0.5 * Math.cos( 3.14159 / 4.0 );
const b = 0.5 * Math.cos( 3.14159 / 16.0 );
const c = 0.5 * Math.cos( 3.14159 / 8.0 );
const d = 0.5 * Math.cos( 3.0 * 3.14159 / 16.0 );
const e = 0.5 * Math.cos( 5.0 * 3.14159 / 16.0 );
const f = 0.5 * Math.cos( 3.0 * 3.14159 / 8.0 );
const g = 0.5 * Math.cos( 7.0 * 3.14159 / 16.0 );
var alpha = new Array( 4 );
var beta = new Array( 4 );
......@@ -1070,31 +1070,31 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
var rowPtr = row * 8;
alpha[ 0 ] = c * data[ rowPtr + 2 ];
alpha[ 1 ] = f * data[ rowPtr + 2 ];
alpha[ 2 ] = c * data[ rowPtr + 6 ];
alpha[ 3 ] = f * data[ rowPtr + 6 ];
alpha[ 0 ] = c * data[ rowPtr + 2 ];
alpha[ 1 ] = f * data[ rowPtr + 2 ];
alpha[ 2 ] = c * data[ rowPtr + 6 ];
alpha[ 3 ] = f * data[ rowPtr + 6 ];
beta[ 0 ] = b * data[ rowPtr + 1 ] + d * data[ rowPtr + 3 ] + e * data[ rowPtr + 5 ] + g * data[ rowPtr + 7 ];
beta[ 1 ] = d * data[ rowPtr + 1 ] - g * data[ rowPtr + 3 ] - b * data[ rowPtr + 5 ] - e * data[ rowPtr + 7 ];
beta[ 2 ] = e * data[ rowPtr + 1 ] - b * data[ rowPtr + 3 ] + g * data[ rowPtr + 5 ] + d * data[ rowPtr + 7 ];
beta[ 3 ] = g * data[ rowPtr + 1 ] - e * data[ rowPtr + 3 ] + d * data[ rowPtr + 5 ] - b * data[ rowPtr + 7 ];
theta[ 0 ] = a * ( data[ rowPtr + 0 ] + data[ rowPtr + 4 ] );
theta[ 3 ] = a * ( data[ rowPtr + 0 ] - data[ rowPtr + 4 ] );
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
gamma[ 0 ] = theta[ 0 ] + theta[ 1 ];
gamma[ 1 ] = theta[ 3 ] + theta[ 2 ];
gamma[ 2 ] = theta[ 3 ] - theta[ 2 ];
gamma[ 3 ] = theta[ 0 ] - theta[ 1 ];
data[ rowPtr + 0 ] = gamma[ 0 ] + beta[ 0 ];
data[ rowPtr + 1 ] = gamma[ 1 ] + beta[ 1 ];
data[ rowPtr + 2 ] = gamma[ 2 ] + beta[ 2 ];
data[ rowPtr + 3 ] = gamma[ 3 ] + beta[ 3 ];
data[ rowPtr + 4 ] = gamma[ 3 ] - beta[ 3 ];
data[ rowPtr + 5 ] = gamma[ 2 ] - beta[ 2 ];
data[ rowPtr + 6 ] = gamma[ 1 ] - beta[ 1 ];
......@@ -1104,29 +1104,29 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
for ( var column = 0; column < 8; ++ column ) {
alpha[ 0 ] = c * data[ 16 + column ];
alpha[ 1 ] = f * data[ 16 + column ];
alpha[ 2 ] = c * data[ 48 + column ];
alpha[ 3 ] = f * data[ 48 + column ];
alpha[ 0 ] = c * data[ 16 + column ];
alpha[ 1 ] = f * data[ 16 + column ];
alpha[ 2 ] = c * data[ 48 + column ];
alpha[ 3 ] = f * data[ 48 + column ];
beta[ 0 ] = b * data[ 8 + column ] + d * data[ 24 + column ] + e * data[ 40 + column ] + g * data[ 56 + column ];
beta[ 1 ] = d * data[ 8 + column ] - g * data[ 24 + column ] - b * data[ 40 + column ] - e * data[ 56 + column ];
beta[ 2 ] = e * data[ 8 + column ] - b * data[ 24 + column ] + g * data[ 40 + column ] + d * data[ 56 + column ];
beta[ 3 ] = g * data [8 + column ] - e * data[ 24 + column ] + d * data[ 40 + column ] - b * data[ 56 + column ];
beta[ 0 ] = b * data[ 8 + column ] + d * data[ 24 + column ] + e * data[ 40 + column ] + g * data[ 56 + column ];
beta[ 1 ] = d * data[ 8 + column ] - g * data[ 24 + column ] - b * data[ 40 + column ] - e * data[ 56 + column ];
beta[ 2 ] = e * data[ 8 + column ] - b * data[ 24 + column ] + g * data[ 40 + column ] + d * data[ 56 + column ];
beta[ 3 ] = g * data[ 8 + column ] - e * data[ 24 + column ] + d * data[ 40 + column ] - b * data[ 56 + column ];
theta[ 0 ] = a * ( data[ column ] + data[ 32 + column ] );
theta[ 3 ] = a * ( data[ column ] - data[ 32 + column ] );
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ];
theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ];
gamma[ 0 ] = theta[ 0 ] + theta[ 1 ];
gamma[ 1 ] = theta[ 3 ] + theta[ 2 ];
gamma[ 2 ] = theta[ 3 ] - theta[ 2 ];
gamma[ 3 ] = theta[ 0 ] - theta[ 1 ];
data[ column ] = gamma[ 0 ] + beta[ 0 ];
data[ 8 + column ] = gamma[ 1 ] + beta[ 1 ];
data[ 0 + column ] = gamma[ 0 ] + beta[ 0 ];
data[ 8 + column ] = gamma[ 1 ] + beta[ 1 ];
data[ 16 + column ] = gamma[ 2 ] + beta[ 2 ];
data[ 24 + column ] = gamma[ 3 ] + beta[ 3 ];
......@@ -1345,15 +1345,15 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
totalDcUncompressedCount: parseInt64( inDataView, inOffset ),
acCompression: parseInt64( inDataView, inOffset )
}
};
if ( dwaHeader.version < 2 )
if ( dwaHeader.version < 2 )
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported';
// Read channel ruleset information
var channelRules = new Array();
var ruleSize = parseUint16( inDataView, inOffset ) - INT16_SIZE;
while ( ruleSize > 0 ) {
var name = parseNullTerminatedString( inDataView.buffer, inOffset );
......@@ -1363,10 +1363,10 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
var index = new Int8Array( [ csc ] )[ 0 ];
var type = parseUint8( inDataView, inOffset );
channelRules.push( {
name: name,
index: index,
type: type,
channelRules.push( {
name: name,
index: index,
type: type,
compression: compression,
} );
......@@ -1454,7 +1454,7 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
array: info.array,
offset: inOffset,
size: dwaHeader.dcCompressedSize
}
};
var dcBuffer = new Uint16Array( uncompressZIP( zlibInfo ).buffer );
inOffset.value += dwaHeader.dcCompressedSize;
......@@ -1516,20 +1516,22 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
for ( var byte = 0; byte < INT16_SIZE * cd.type; ++ byte ) {
outBuffer[ rowOffsetBytes++ ] = rleBuffer[ rleOffset + byte * cd.width * cd.height ];
outBuffer[ rowOffsetBytes ++ ] = rleBuffer[ rleOffset + byte * cd.width * cd.height ];
}
rleOffset++
rleOffset ++;
}
row++;
row ++;
}
break;
case LOSSY_DCT: // skip
default:
throw 'EXRLoader.parse: unsupported channel compression';
......@@ -1652,45 +1654,60 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
}
// https://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript
var encodeFloat16 = ( function() {
var floatView = new Float32Array(1);
var int32View = new Int32Array(floatView.buffer);
return function toHalf( fval ) {
floatView[ 0 ] = fval;
var fbits = int32View[ 0 ];
var sign = ( fbits >> 16 ) & 0x8000; // sign only
var val = ( fbits & 0x7fffffff ) + 0x1000; // rounded value
if ( val >= 0x47800000 ) { // might be or become NaN/Inf
if ( ( fbits & 0x7fffffff ) >= 0x47800000 ) {
// is or must become NaN/Inf
if( val < 0x7f800000 ) { // was value but too large
return sign | 0x7c00; // make it +/-Inf
}
return sign | 0x7c00 | // remains +/-Inf or NaN
( fbits & 0x007fffff ) >> 13; // keep NaN (and Inf) bits
var encodeFloat16 = ( function () {
// Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
var floatView = new Float32Array( 1 );
var int32View = new Int32Array( floatView.buffer );
/* This method is faster than the OpenEXR implementation (very often
* used, eg. in Ogre), with the additional benefit of rounding, inspired
* by James Tursa?s half-precision code. */
return function toHalf( val ) {
floatView[ 0 ] = val;
var x = int32View[ 0 ];
var bits = ( x >> 16 ) & 0x8000; /* Get the sign */
var m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */
var e = ( x >> 23 ) & 0xff; /* Using int is faster here */
/* If zero, or denormal, or exponent underflows too much for a denormal
* half, return signed zero. */
if ( e < 103 ) return bits;
/* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
if ( e > 142 ) {
bits |= 0x7c00;
/* If exponent was 0xff and one mantissa bit was set, it means NaN,
* not Inf, so make sure we set one mantissa bit too. */
bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff );
return bits;
}
/* If exponent underflows but not too much, return a denormal */
if ( e < 113 ) {
m |= 0x0800;
/* Extra rounding may overflow and set mantissa to 0 and exponent
* to 1, which is OK. */
bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 );
return bits;
}
return sign | 0x7bff; // unrounded not quite Inf
}
if ( val >= 0x38800000 ) { // remains normalized value
return sign | val - 0x38000000 >> 13; // exp - 127 + 15
}
if ( val < 0x33000000 ) { // too small for subnormal
return sign; // becomes +/-0
}
val = ( fbits & 0x7fffffff ) >> 23; // tmp exp for subnormal calc
return sign | ( ( fbits & 0x7fffff | 0x800000 ) // add subnormal bit
+ ( 0x800000 >>> val - 102 ) // round depending on cut off
>> 126 - val ); // div by 2^(1-(exp-127+15)) and >> 13 | exp=
bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 );
/* Extra rounding. An overflow will set mantissa to 0 and increment
* the exponent, which is OK. */
bits += m & 1;
return bits;
};
} () );
} )();
function parseUint16( dataView, offset ) {
......@@ -1936,7 +1953,7 @@ EXRLoader.prototype = Object.assign( Object.create( DataTextureLoader.prototype
scanlineBlockSize = 256;
uncompress = uncompressDWA;
break;
default:
throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册