|
|
@@ -1022,6 +1022,81 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function lossyDctChannelDecode( channelIndex, rowPtrs, channelData, acBuffer, dcBuffer, outBuffer ) {
|
|
|
+
|
|
|
+ const dataView = new DataView( outBuffer.buffer );
|
|
|
+ const cd = channelData[ channelIndex ];
|
|
|
+ const width = cd.width;
|
|
|
+ const height = cd.height;
|
|
|
+
|
|
|
+ const numBlocksX = Math.ceil( width / 8.0 );
|
|
|
+ const numBlocksY = Math.ceil( height / 8.0 );
|
|
|
+ const numFullBlocksX = Math.floor( width / 8.0 );
|
|
|
+ const leftoverX = width - ( numBlocksX - 1 ) * 8;
|
|
|
+ const leftoverY = height - ( numBlocksY - 1 ) * 8;
|
|
|
+
|
|
|
+ const currAcComp = { value: 0 };
|
|
|
+ let currDcComp = 0;
|
|
|
+ const dctData = new Float32Array( 64 );
|
|
|
+ const halfZigBlock = new Uint16Array( 64 );
|
|
|
+ const rowBlock = new Uint16Array( numBlocksX * 64 );
|
|
|
+
|
|
|
+ for ( let blocky = 0; blocky < numBlocksY; ++ blocky ) {
|
|
|
+
|
|
|
+ let maxY = 8;
|
|
|
+
|
|
|
+ if ( blocky == numBlocksY - 1 ) maxY = leftoverY;
|
|
|
+
|
|
|
+ for ( let blockx = 0; blockx < numBlocksX; ++ blockx ) {
|
|
|
+
|
|
|
+ halfZigBlock.fill( 0 );
|
|
|
+ halfZigBlock[ 0 ] = dcBuffer[ currDcComp ++ ];
|
|
|
+ unRleAC( currAcComp, acBuffer, halfZigBlock );
|
|
|
+ unZigZag( halfZigBlock, dctData );
|
|
|
+ dctInverse( dctData );
|
|
|
+ convertToHalf( dctData, rowBlock, blockx * 64 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // Write decoded data to output buffer
|
|
|
+ for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) {
|
|
|
+
|
|
|
+ let offset = rowPtrs[ channelIndex ][ y ];
|
|
|
+
|
|
|
+ for ( let blockx = 0; blockx < numFullBlocksX; ++ blockx ) {
|
|
|
+
|
|
|
+ const src = blockx * 64 + ( ( y & 0x7 ) * 8 );
|
|
|
+
|
|
|
+ for ( let x = 0; x < 8; ++ x ) {
|
|
|
+
|
|
|
+ dataView.setUint16( offset + x * INT16_SIZE * cd.type, rowBlock[ src + x ], true );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ offset += 8 * INT16_SIZE * cd.type;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( numBlocksX != numFullBlocksX ) {
|
|
|
+
|
|
|
+ const src = numFullBlocksX * 64 + ( ( y & 0x7 ) * 8 );
|
|
|
+
|
|
|
+ for ( let x = 0; x < leftoverX; ++ x ) {
|
|
|
+
|
|
|
+ dataView.setUint16( offset + x * INT16_SIZE * cd.type, rowBlock[ src + x ], true );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ cd.decoded = true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
function unRleAC( currAcComp, acBuffer, halfZigBlock ) {
|
|
|
|
|
|
let acValue;
|
|
|
@@ -1634,8 +1709,12 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
}
|
|
|
|
|
|
- // Lossy DCT decode RGB channels
|
|
|
- lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer );
|
|
|
+ // Decode lossy DCT data if we have a valid color space conversion set with the first RGB channel present
|
|
|
+ if ( cscSet.idx[ 0 ] !== undefined && channelData[ cscSet.idx[ 0 ] ] ) {
|
|
|
+
|
|
|
+ lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
// Decode other channels
|
|
|
for ( let i = 0; i < channelData.length; ++ i ) {
|
|
|
@@ -1673,7 +1752,11 @@ class EXRLoader extends DataTextureLoader {
|
|
|
|
|
|
break;
|
|
|
|
|
|
- case LOSSY_DCT: // skip
|
|
|
+ case LOSSY_DCT:
|
|
|
+
|
|
|
+ lossyDctChannelDecode( i, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer );
|
|
|
+
|
|
|
+ break;
|
|
|
|
|
|
default:
|
|
|
throw new Error( 'EXRLoader.parse: unsupported channel compression' );
|