|
@@ -1,8 +1,9 @@
|
|
|
/**
|
|
|
* @author Richard M. / https://github.com/richardmonette
|
|
|
+ * @author ScieCode / http://github.com/sciecode
|
|
|
*
|
|
|
- * OpenEXR loader which, currently, supports reading 16 bit half data, in either
|
|
|
- * uncompressed or PIZ wavelet compressed form.
|
|
|
+ * OpenEXR loader which, currently, supports uncompressed, ZIP(S), RLE and PIZ wavelet compression.
|
|
|
+ * Supports reading 16 and 32 bit data format, except for PIZ compression which only reads 16-bit data.
|
|
|
*
|
|
|
* Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita
|
|
|
* implementation, so I have preserved their copyright notices.
|
|
@@ -690,83 +691,106 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
|
|
|
|
|
|
}
|
|
|
|
|
|
- function decompressPIZ( outBuffer, outOffset, uInt8Array, inDataView, inOffset, tmpBufSize, num_channels, exrChannelInfos, dataWidth, num_lines ) {
|
|
|
+ function predictor( source ) {
|
|
|
|
|
|
- var bitmap = new Uint8Array( BITMAP_SIZE );
|
|
|
+ for ( var t = 1; t < source.length; t ++ ) {
|
|
|
|
|
|
- var minNonZero = parseUint16( inDataView, inOffset );
|
|
|
- var maxNonZero = parseUint16( inDataView, inOffset );
|
|
|
+ var d = source[ t - 1 ] + source[ t ] - 128;
|
|
|
+ source[ t ] = d;
|
|
|
|
|
|
- if ( maxNonZero >= BITMAP_SIZE ) {
|
|
|
+ }
|
|
|
|
|
|
- throw 'Something is wrong with PIZ_COMPRESSION BITMAP_SIZE';
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ function interleaveScalar( source, out ) {
|
|
|
|
|
|
- if ( minNonZero <= maxNonZero ) {
|
|
|
+ var t1 = 0;
|
|
|
+ var t2 = Math.floor( ( source.length + 1 ) / 2 );
|
|
|
+ var s = 0;
|
|
|
+ var stop = source.length - 1;
|
|
|
|
|
|
- for ( var i = 0; i < maxNonZero - minNonZero + 1; i ++ ) {
|
|
|
+ while ( true ) {
|
|
|
|
|
|
- bitmap[ i + minNonZero ] = parseUint8( inDataView, inOffset );
|
|
|
+ if ( s > stop ) break;
|
|
|
+ out[ s ++ ] = source[ t1 ++ ];
|
|
|
|
|
|
- }
|
|
|
+ if ( s > stop ) break;
|
|
|
+ out[ s ++ ] = source[ t2 ++ ];
|
|
|
|
|
|
}
|
|
|
|
|
|
- var lut = new Uint16Array( USHORT_RANGE );
|
|
|
- reverseLutFromBitmap( bitmap, lut );
|
|
|
+ }
|
|
|
|
|
|
- var length = parseUint32( inDataView, inOffset );
|
|
|
+ function decodeRunLength( source ) {
|
|
|
|
|
|
- hufUncompress( uInt8Array, inDataView, inOffset, length, outBuffer, outOffset, tmpBufSize );
|
|
|
+ var size = source.byteLength;
|
|
|
+ var out = new Array();
|
|
|
+ var p = 0;
|
|
|
|
|
|
- var pizChannelData = new Array( num_channels );
|
|
|
+ var reader = new DataView( source );
|
|
|
|
|
|
- var outBufferEnd = 0;
|
|
|
+ while ( size > 0 ) {
|
|
|
|
|
|
- for ( var i = 0; i < num_channels; i ++ ) {
|
|
|
+ var l = reader.getInt8( p++ );
|
|
|
|
|
|
- pizChannelData[ i ] = {};
|
|
|
- pizChannelData[ i ][ 'start' ] = outBufferEnd;
|
|
|
- pizChannelData[ i ][ 'end' ] = pizChannelData[ i ][ 'start' ];
|
|
|
- pizChannelData[ i ][ 'nx' ] = dataWidth;
|
|
|
- pizChannelData[ i ][ 'ny' ] = num_lines;
|
|
|
- pizChannelData[ i ][ 'size' ] = 1;
|
|
|
+ if ( l < 0 ) {
|
|
|
|
|
|
- outBufferEnd += pizChannelData[ i ].nx * pizChannelData[ i ].ny * pizChannelData[ i ].size;
|
|
|
+ var count = -l;
|
|
|
+ size -= count + 1;
|
|
|
|
|
|
- }
|
|
|
+ for ( var i = 0; i < count; i++ ) {
|
|
|
|
|
|
- var fooOffset = 0;
|
|
|
+ out.push( reader.getUint8( p++ ) );
|
|
|
|
|
|
- for ( var i = 0; i < num_channels; i ++ ) {
|
|
|
+ }
|
|
|
|
|
|
- for ( var j = 0; j < pizChannelData[ i ].size; ++ j ) {
|
|
|
|
|
|
- fooOffset += wav2Decode(
|
|
|
- j + fooOffset,
|
|
|
- outBuffer,
|
|
|
- pizChannelData[ i ].nx,
|
|
|
- pizChannelData[ i ].size,
|
|
|
- pizChannelData[ i ].ny,
|
|
|
- pizChannelData[ i ].nx * pizChannelData[ i ].size
|
|
|
- );
|
|
|
+ } else {
|
|
|
+
|
|
|
+ var count = l;
|
|
|
+ size -= 2;
|
|
|
+
|
|
|
+ var value = reader.getUint8( p++ );
|
|
|
+
|
|
|
+ for ( var i = 0; i < count+1; i++ ) {
|
|
|
+
|
|
|
+ out.push( value );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- applyLut( lut, outBuffer, outBufferEnd );
|
|
|
+ return out;
|
|
|
|
|
|
- return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ function uncompressRaw( info ) {
|
|
|
+
|
|
|
+ return new DataView( info.array.buffer, info.offset.value, info.size );
|
|
|
|
|
|
}
|
|
|
|
|
|
- function decompressZIP( inDataView, offset, compressedSize, pixelType ) {
|
|
|
+ function uncompressRLE( info ) {
|
|
|
+
|
|
|
+ var compressed = info.viewer.buffer.slice( info.offset.value, info.offset.value + info.size );
|
|
|
|
|
|
- var raw;
|
|
|
+ var rawBuffer = new Uint8Array( decodeRunLength( compressed ) );
|
|
|
+ var tmpBuffer = new Uint8Array( rawBuffer.length );
|
|
|
+
|
|
|
+ predictor( rawBuffer ); // revert predictor
|
|
|
+
|
|
|
+ interleaveScalar( rawBuffer, tmpBuffer ); // interleave pixels
|
|
|
+
|
|
|
+ return new DataView( tmpBuffer.buffer );
|
|
|
|
|
|
- var compressed = new Uint8Array( inDataView.buffer.slice( offset.value, offset.value + compressedSize ) );
|
|
|
+ }
|
|
|
+
|
|
|
+ function uncompressZIP( info ) {
|
|
|
+
|
|
|
+ var compressed = info.array.slice( info.offset.value, info.offset.value + info.size );
|
|
|
|
|
|
if ( typeof Zlib === 'undefined' ) {
|
|
|
|
|
@@ -779,52 +803,109 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
|
|
|
var rawBuffer = new Uint8Array( inflate.decompress().buffer );
|
|
|
var tmpBuffer = new Uint8Array( rawBuffer.length );
|
|
|
|
|
|
- reconstruct_scalar( rawBuffer ); // reorder pixels
|
|
|
+ predictor( rawBuffer ); // revert predictor
|
|
|
+
|
|
|
+ interleaveScalar( rawBuffer, tmpBuffer ); // interleave pixels
|
|
|
|
|
|
- interleave_scalar( rawBuffer, tmpBuffer ); // interleave pixels
|
|
|
+ return new DataView( tmpBuffer.buffer );
|
|
|
|
|
|
- if ( pixelType == 1 ) {
|
|
|
+ }
|
|
|
+
|
|
|
+ function uncompressPIZ( info ) {
|
|
|
|
|
|
- raw = new Uint16Array( tmpBuffer.buffer );
|
|
|
+ var inDataView = info.viewer;
|
|
|
+ var inOffset = { value: info.offset.value };
|
|
|
|
|
|
- } else if ( pixelType == 2 ) {
|
|
|
+ var tmpBufSize = info.width * scanlineBlockSize * ( EXRHeader.channels.length * BYTES_PER_HALF );
|
|
|
+ var outBuffer = new Uint16Array( tmpBufSize );
|
|
|
+ var outOffset = { value: 0 };
|
|
|
|
|
|
- raw = new Float32Array( tmpBuffer.buffer );
|
|
|
+ var bitmap = new Uint8Array( BITMAP_SIZE );
|
|
|
+
|
|
|
+ var minNonZero = parseUint16( inDataView, inOffset );
|
|
|
+ var maxNonZero = parseUint16( inDataView, inOffset );
|
|
|
+
|
|
|
+ if ( maxNonZero >= BITMAP_SIZE ) {
|
|
|
+
|
|
|
+ throw 'Something is wrong with PIZ_COMPRESSION BITMAP_SIZE';
|
|
|
|
|
|
}
|
|
|
|
|
|
- return raw;
|
|
|
+ if ( minNonZero <= maxNonZero ) {
|
|
|
|
|
|
- }
|
|
|
+ for ( var i = 0; i < maxNonZero - minNonZero + 1; i ++ ) {
|
|
|
|
|
|
- function reconstruct_scalar( source ) {
|
|
|
+ bitmap[ i + minNonZero ] = parseUint8( inDataView, inOffset );
|
|
|
|
|
|
- for ( let t = 1; t < source.length; t ++ ) {
|
|
|
+ }
|
|
|
|
|
|
- var d = source[ t - 1 ] + source[ t ] - 128;
|
|
|
- source[ t ] = d;
|
|
|
+ }
|
|
|
+
|
|
|
+ var lut = new Uint16Array( USHORT_RANGE );
|
|
|
+ reverseLutFromBitmap( bitmap, lut );
|
|
|
+
|
|
|
+ var length = parseUint32( inDataView, inOffset );
|
|
|
+
|
|
|
+ hufUncompress( info.array, inDataView, inOffset, length, outBuffer, outOffset, tmpBufSize );
|
|
|
+
|
|
|
+ var pizChannelData = new Array( info.channels );
|
|
|
+
|
|
|
+ var outBufferEnd = 0;
|
|
|
+
|
|
|
+ for ( var i = 0; i < info.channels; i ++ ) {
|
|
|
+
|
|
|
+ pizChannelData[ i ] = {};
|
|
|
+ pizChannelData[ i ][ 'start' ] = outBufferEnd;
|
|
|
+ pizChannelData[ i ][ 'end' ] = pizChannelData[ i ][ 'start' ];
|
|
|
+ pizChannelData[ i ][ 'nx' ] = info.width;
|
|
|
+ pizChannelData[ i ][ 'ny' ] = info.lines;
|
|
|
+ pizChannelData[ i ][ 'size' ] = 1;
|
|
|
+
|
|
|
+ outBufferEnd += pizChannelData[ i ].nx * pizChannelData[ i ].ny * pizChannelData[ i ].size;
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ var fooOffset = 0;
|
|
|
|
|
|
- function interleave_scalar( source, out ) {
|
|
|
+ for ( var i = 0; i < info.channels; i ++ ) {
|
|
|
|
|
|
- var t1 = 0;
|
|
|
- var t2 = Math.floor( ( source.length + 1 ) / 2 );
|
|
|
- var s = 0;
|
|
|
- var stop = source.length - 1;
|
|
|
+ for ( var j = 0; j < pizChannelData[ i ].size; ++ j ) {
|
|
|
|
|
|
- while ( true ) {
|
|
|
+ fooOffset += wav2Decode(
|
|
|
+ j + fooOffset,
|
|
|
+ outBuffer,
|
|
|
+ pizChannelData[ i ].nx,
|
|
|
+ pizChannelData[ i ].size,
|
|
|
+ pizChannelData[ i ].ny,
|
|
|
+ pizChannelData[ i ].nx * pizChannelData[ i ].size
|
|
|
+ );
|
|
|
|
|
|
- if ( s > stop ) break;
|
|
|
- out[ s ++ ] = source[ t1 ++ ];
|
|
|
+ }
|
|
|
|
|
|
- if ( s > stop ) break;
|
|
|
- out[ s ++ ] = source[ t2 ++ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ applyLut( lut, outBuffer, outBufferEnd );
|
|
|
+
|
|
|
+ var tmpBuffer = new Uint8Array( outBuffer.buffer.byteLength );
|
|
|
+ var tmpOffset = 0;
|
|
|
+ var n = info.width * 2;
|
|
|
+
|
|
|
+ for ( var y = 0; y < info.lines; y++ ) {
|
|
|
+
|
|
|
+ for ( var c = 0; c < info.channels; c++ ) {
|
|
|
+
|
|
|
+ var cd = pizChannelData[ c ];
|
|
|
+ var cp = new Uint8Array( outBuffer.buffer, cd.end * 2 + y * n, n );
|
|
|
+
|
|
|
+ tmpBuffer.set( cp, tmpOffset );
|
|
|
+ tmpOffset += n;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
+ return new DataView( tmpBuffer.buffer );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
function parseNullTerminatedString( buffer, offset ) {
|
|
@@ -1124,17 +1205,92 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
|
|
|
}
|
|
|
|
|
|
// offsets
|
|
|
-
|
|
|
var dataWindowHeight = EXRHeader.dataWindow.yMax + 1;
|
|
|
- var scanlineBlockSize = 1; // 1 for NO_COMPRESSION
|
|
|
+
|
|
|
+ var uncompress;
|
|
|
+ var scanlineBlockSize;
|
|
|
+
|
|
|
+ switch ( EXRHeader.compression ) {
|
|
|
|
|
|
- if ( EXRHeader.compression === 'PIZ_COMPRESSION' ) {
|
|
|
+ case 'NO_COMPRESSION':
|
|
|
|
|
|
- scanlineBlockSize = 32;
|
|
|
+ scanlineBlockSize = 1;
|
|
|
+ uncompress = uncompressRaw;
|
|
|
+ break;
|
|
|
|
|
|
- } else if ( EXRHeader.compression === 'ZIP_COMPRESSION' ) {
|
|
|
+ case 'RLE_COMPRESSION':
|
|
|
+
|
|
|
+ scanlineBlockSize = 1;
|
|
|
+ uncompress = uncompressRLE;
|
|
|
+ break;
|
|
|
|
|
|
- scanlineBlockSize = 16;
|
|
|
+ case 'ZIPS_COMPRESSION':
|
|
|
+
|
|
|
+ scanlineBlockSize = 1;
|
|
|
+ uncompress = uncompressZIP;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'ZIP_COMPRESSION':
|
|
|
+
|
|
|
+ scanlineBlockSize = 16;
|
|
|
+ uncompress = uncompressZIP;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'PIZ_COMPRESSION':
|
|
|
+
|
|
|
+ scanlineBlockSize = 32;
|
|
|
+ uncompress = uncompressPIZ;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+
|
|
|
+ throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported';
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var size_t;
|
|
|
+ var getValue;
|
|
|
+
|
|
|
+ // mixed pixelType not supported
|
|
|
+ var pixelType = EXRHeader.channels[ 0 ].pixelType;
|
|
|
+
|
|
|
+ if ( pixelType === 1 ) { // half
|
|
|
+
|
|
|
+ switch ( this.type ) {
|
|
|
+
|
|
|
+ case THREE.FloatType:
|
|
|
+
|
|
|
+ getValue = parseFloat16;
|
|
|
+ size_t = INT16_SIZE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case THREE.HalfFloatType:
|
|
|
+
|
|
|
+ getValue = parseUint16;
|
|
|
+ size_t = INT16_SIZE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if ( pixelType === 2 ) { // float
|
|
|
+
|
|
|
+ switch ( this.type ) {
|
|
|
+
|
|
|
+ case THREE.FloatType:
|
|
|
+
|
|
|
+ getValue = parseFloat32;
|
|
|
+ size_t = FLOAT32_SIZE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case THREE.HalfFloatType:
|
|
|
+
|
|
|
+ throw 'EXRLoader.parse: unsupported HalfFloatType texture for FloatType image file.';
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ throw 'EXRLoader.parse: unsupported pixelType ' + pixelType + ' for ' + EXRHeader.compression + '.';
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1196,168 +1352,58 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
|
|
|
A: 3
|
|
|
};
|
|
|
|
|
|
- if ( EXRHeader.compression === 'NO_COMPRESSION' ) {
|
|
|
-
|
|
|
- for ( var y = 0; y < height; y ++ ) {
|
|
|
-
|
|
|
- var y_scanline = parseUint32( bufferDataView, offset );
|
|
|
- parseUint32( bufferDataView, offset ); // dataSize
|
|
|
+ var compressionInfo = {
|
|
|
|
|
|
- for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) {
|
|
|
-
|
|
|
- var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
|
|
|
-
|
|
|
- if ( EXRHeader.channels[ channelID ].pixelType === 1 ) { // half
|
|
|
-
|
|
|
- for ( var x = 0; x < width; x ++ ) {
|
|
|
+ array: uInt8Array,
|
|
|
+ viewer: bufferDataView,
|
|
|
+ offset: offset,
|
|
|
+ channels: EXRHeader.channels.length,
|
|
|
+ width: width,
|
|
|
+ lines: scanlineBlockSize,
|
|
|
+ size: 0
|
|
|
|
|
|
- switch ( this.type ) {
|
|
|
-
|
|
|
- case THREE.FloatType:
|
|
|
-
|
|
|
- var val = parseFloat16( bufferDataView, offset );
|
|
|
- break;
|
|
|
-
|
|
|
- case THREE.HalfFloatType:
|
|
|
-
|
|
|
- var val = parseUint16( bufferDataView, offset );
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- byteArray[ ( ( ( height - y_scanline ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- throw 'EXRLoader.parse: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + ' for ' + EXRHeader.compression + '.';
|
|
|
-
|
|
|
- }
|
|
|
+ };
|
|
|
|
|
|
- }
|
|
|
+ if ( EXRHeader.compression === 'NO_COMPRESSION' ||
|
|
|
+ EXRHeader.compression === 'ZIP_COMPRESSION' ||
|
|
|
+ EXRHeader.compression === 'ZIPS_COMPRESSION' ||
|
|
|
+ EXRHeader.compression === 'RLE_COMPRESSION' ||
|
|
|
+ EXRHeader.compression === 'PIZ_COMPRESSION' ) {
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- } else if ( EXRHeader.compression === 'PIZ_COMPRESSION' ) {
|
|
|
+ var size;
|
|
|
+ var viewer;
|
|
|
+ var tmpOffset = { value: 0 };
|
|
|
|
|
|
for ( var scanlineBlockIdx = 0; scanlineBlockIdx < height / scanlineBlockSize; scanlineBlockIdx ++ ) {
|
|
|
|
|
|
parseUint32( bufferDataView, offset ); // line_no
|
|
|
- parseUint32( bufferDataView, offset ); // data_len
|
|
|
-
|
|
|
- var tmpBufferSize = width * scanlineBlockSize * ( EXRHeader.channels.length * BYTES_PER_HALF );
|
|
|
- var tmpBuffer = new Uint16Array( tmpBufferSize );
|
|
|
- var tmpOffset = { value: 0 };
|
|
|
-
|
|
|
- decompressPIZ( tmpBuffer, tmpOffset, uInt8Array, bufferDataView, offset, tmpBufferSize, EXRHeader.channels.length, EXRHeader.channels, width, scanlineBlockSize );
|
|
|
-
|
|
|
- for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) {
|
|
|
-
|
|
|
- for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) {
|
|
|
-
|
|
|
- var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
|
|
|
-
|
|
|
- if ( EXRHeader.channels[ channelID ].pixelType === 1 ) { // half
|
|
|
-
|
|
|
- for ( var x = 0; x < width; x ++ ) {
|
|
|
-
|
|
|
- var idx = ( channelID * ( scanlineBlockSize * width ) ) + ( line_y * width ) + x;
|
|
|
-
|
|
|
- switch ( this.type ) {
|
|
|
-
|
|
|
- case THREE.FloatType:
|
|
|
-
|
|
|
- var val = decodeFloat16( tmpBuffer[ idx ] );
|
|
|
- break;
|
|
|
-
|
|
|
- case THREE.HalfFloatType:
|
|
|
-
|
|
|
- var val = tmpBuffer[ idx ];
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var true_y = line_y + ( scanlineBlockIdx * scanlineBlockSize );
|
|
|
-
|
|
|
- byteArray[ ( ( ( height - true_y ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- throw 'EXRLoader.parse: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + ' for ' + EXRHeader.compression + '.';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
+ size = parseUint32( bufferDataView, offset ); // data_len
|
|
|
|
|
|
- }
|
|
|
+ compressionInfo.offset = offset;
|
|
|
+ compressionInfo.size = size;
|
|
|
|
|
|
- } else if ( EXRHeader.compression === 'ZIP_COMPRESSION' ||
|
|
|
- EXRHeader.compression === 'ZIPS_COMPRESSION' ) {
|
|
|
+ viewer = uncompress( compressionInfo );
|
|
|
|
|
|
- for ( var scanlineBlockIdx = 0; scanlineBlockIdx < height / scanlineBlockSize; scanlineBlockIdx ++ ) {
|
|
|
-
|
|
|
- parseUint32( bufferDataView, offset ); // line_no
|
|
|
- var compressedSize = parseUint32( bufferDataView, offset ); // data_len
|
|
|
+ offset.value += size;
|
|
|
|
|
|
- var raw = decompressZIP( bufferDataView, offset, compressedSize, EXRHeader.channels[ 0 ].pixelType );
|
|
|
+ for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) {
|
|
|
|
|
|
- offset.value += compressedSize;
|
|
|
+ var true_y = line_y + ( scanlineBlockIdx * scanlineBlockSize );
|
|
|
|
|
|
- for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) {
|
|
|
+ if ( true_y >= height ) break;
|
|
|
|
|
|
for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) {
|
|
|
|
|
|
- for ( var x = 0; x < width; x ++ ) {
|
|
|
+ var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
|
|
|
|
|
|
- var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
|
|
|
+ for ( var x = 0; x < width; x ++ ) {
|
|
|
|
|
|
var idx = ( line_y * ( EXRHeader.channels.length * width ) ) + ( channelID * width ) + x;
|
|
|
+ tmpOffset.value = idx * size_t;
|
|
|
|
|
|
- if ( EXRHeader.channels[ channelID ].pixelType === 1 ) { // half
|
|
|
-
|
|
|
- switch ( this.type ) {
|
|
|
-
|
|
|
- case THREE.FloatType:
|
|
|
-
|
|
|
- var val = decodeFloat16( raw[ idx ] );
|
|
|
- break;
|
|
|
-
|
|
|
- case THREE.HalfFloatType:
|
|
|
-
|
|
|
- var val = raw[ idx ];
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
+ var val = getValue( viewer, tmpOffset );
|
|
|
|
|
|
- } else if ( EXRHeader.channels[ channelID ].pixelType === 2 ) { // float
|
|
|
-
|
|
|
- switch ( this.type ) {
|
|
|
-
|
|
|
- case THREE.FloatType:
|
|
|
-
|
|
|
- var val = raw[ idx ];
|
|
|
- break;
|
|
|
-
|
|
|
- case THREE.HalfFloatType:
|
|
|
-
|
|
|
- throw 'EXRLoader.parse: unsupported HalfFloatType texture for FloatType image file.';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- throw 'EXRLoader.parse: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + ' for ' + EXRHeader.compression + '.';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var true_y = line_y + ( scanlineBlockIdx * scanlineBlockSize );
|
|
|
-
|
|
|
- byteArray[ ( ( ( height - true_y ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
|
|
|
+ byteArray[ ( ( ( height - 1 - true_y ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1367,10 +1413,6 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
|
|
|
|
|
|
}
|
|
|
|
|
|
- } else {
|
|
|
-
|
|
|
- throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported';
|
|
|
-
|
|
|
}
|
|
|
|
|
|
return {
|
|
@@ -1425,4 +1467,4 @@ THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoade
|
|
|
|
|
|
}
|
|
|
|
|
|
-} );
|
|
|
+} );
|