Skip to content

Commit f9591c4

Browse files
authored
EXRLoader: Added lossyDctChannelDecode (#31482)
* EXRLoader: Added lossyDctChannelDecode. * Clean up. * Clean up. * Clean up. * Improved comment.
1 parent 173555e commit f9591c4

File tree

1 file changed

+86
-3
lines changed

1 file changed

+86
-3
lines changed

examples/jsm/loaders/EXRLoader.js

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,81 @@ class EXRLoader extends DataTextureLoader {
10221022

10231023
}
10241024

1025+
function lossyDctChannelDecode( channelIndex, rowPtrs, channelData, acBuffer, dcBuffer, outBuffer ) {
1026+
1027+
const dataView = new DataView( outBuffer.buffer );
1028+
const cd = channelData[ channelIndex ];
1029+
const width = cd.width;
1030+
const height = cd.height;
1031+
1032+
const numBlocksX = Math.ceil( width / 8.0 );
1033+
const numBlocksY = Math.ceil( height / 8.0 );
1034+
const numFullBlocksX = Math.floor( width / 8.0 );
1035+
const leftoverX = width - ( numBlocksX - 1 ) * 8;
1036+
const leftoverY = height - ( numBlocksY - 1 ) * 8;
1037+
1038+
const currAcComp = { value: 0 };
1039+
let currDcComp = 0;
1040+
const dctData = new Float32Array( 64 );
1041+
const halfZigBlock = new Uint16Array( 64 );
1042+
const rowBlock = new Uint16Array( numBlocksX * 64 );
1043+
1044+
for ( let blocky = 0; blocky < numBlocksY; ++ blocky ) {
1045+
1046+
let maxY = 8;
1047+
1048+
if ( blocky == numBlocksY - 1 ) maxY = leftoverY;
1049+
1050+
for ( let blockx = 0; blockx < numBlocksX; ++ blockx ) {
1051+
1052+
halfZigBlock.fill( 0 );
1053+
halfZigBlock[ 0 ] = dcBuffer[ currDcComp ++ ];
1054+
unRleAC( currAcComp, acBuffer, halfZigBlock );
1055+
unZigZag( halfZigBlock, dctData );
1056+
dctInverse( dctData );
1057+
convertToHalf( dctData, rowBlock, blockx * 64 );
1058+
1059+
}
1060+
1061+
// Write decoded data to output buffer
1062+
for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) {
1063+
1064+
let offset = rowPtrs[ channelIndex ][ y ];
1065+
1066+
for ( let blockx = 0; blockx < numFullBlocksX; ++ blockx ) {
1067+
1068+
const src = blockx * 64 + ( ( y & 0x7 ) * 8 );
1069+
1070+
for ( let x = 0; x < 8; ++ x ) {
1071+
1072+
dataView.setUint16( offset + x * INT16_SIZE * cd.type, rowBlock[ src + x ], true );
1073+
1074+
}
1075+
1076+
offset += 8 * INT16_SIZE * cd.type;
1077+
1078+
}
1079+
1080+
if ( numBlocksX != numFullBlocksX ) {
1081+
1082+
const src = numFullBlocksX * 64 + ( ( y & 0x7 ) * 8 );
1083+
1084+
for ( let x = 0; x < leftoverX; ++ x ) {
1085+
1086+
dataView.setUint16( offset + x * INT16_SIZE * cd.type, rowBlock[ src + x ], true );
1087+
1088+
}
1089+
1090+
}
1091+
1092+
}
1093+
1094+
}
1095+
1096+
cd.decoded = true;
1097+
1098+
}
1099+
10251100
function unRleAC( currAcComp, acBuffer, halfZigBlock ) {
10261101

10271102
let acValue;
@@ -1634,8 +1709,12 @@ class EXRLoader extends DataTextureLoader {
16341709

16351710
}
16361711

1637-
// Lossy DCT decode RGB channels
1638-
lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer );
1712+
// Decode lossy DCT data if we have a valid color space conversion set with the first RGB channel present
1713+
if ( cscSet.idx[ 0 ] !== undefined && channelData[ cscSet.idx[ 0 ] ] ) {
1714+
1715+
lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer );
1716+
1717+
}
16391718

16401719
// Decode other channels
16411720
for ( let i = 0; i < channelData.length; ++ i ) {
@@ -1673,7 +1752,11 @@ class EXRLoader extends DataTextureLoader {
16731752

16741753
break;
16751754

1676-
case LOSSY_DCT: // skip
1755+
case LOSSY_DCT:
1756+
1757+
lossyDctChannelDecode( i, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer );
1758+
1759+
break;
16771760

16781761
default:
16791762
throw new Error( 'EXRLoader.parse: unsupported channel compression' );

0 commit comments

Comments
 (0)