@@ -18,21 +18,28 @@ export class SpzReader {
1818 fileBytes : Uint8Array ;
1919 reader : GunzipReader ;
2020
21- version : number ;
22- numSplats : number ;
23- shDegree : number ;
24- fractionalBits : number ;
25- flags : number ;
26- flagAntiAlias : boolean ;
27- reserved : number ;
28- parsed : boolean ;
21+ version = - 1 ;
22+ numSplats = 0 ;
23+ shDegree = 0 ;
24+ fractionalBits = 0 ;
25+ flags = 0 ;
26+ flagAntiAlias = false ;
27+ reserved = 0 ;
28+ headerParsed = false ;
29+ parsed = false ;
2930
3031 constructor ( { fileBytes } : { fileBytes : Uint8Array | ArrayBuffer } ) {
3132 this . fileBytes =
3233 fileBytes instanceof ArrayBuffer ? new Uint8Array ( fileBytes ) : fileBytes ;
3334 this . reader = new GunzipReader ( { fileBytes : this . fileBytes } ) ;
35+ }
36+
37+ async parseHeader ( ) {
38+ if ( this . headerParsed ) {
39+ throw new Error ( "SPZ file header already parsed" ) ;
40+ }
3441
35- const header = new DataView ( this . reader . read ( 16 ) . buffer ) ;
42+ const header = new DataView ( ( await this . reader . read ( 16 ) ) . buffer ) ;
3643 if ( header . getUint32 ( 0 , true ) !== 0x5053474e ) {
3744 throw new Error ( "Invalid SPZ file" ) ;
3845 }
@@ -47,10 +54,11 @@ export class SpzReader {
4754 this . flags = header . getUint8 ( 14 ) ;
4855 this . flagAntiAlias = ( this . flags & 0x01 ) !== 0 ;
4956 this . reserved = header . getUint8 ( 15 ) ;
57+ this . headerParsed = true ;
5058 this . parsed = false ;
5159 }
5260
53- parseSplats (
61+ async parseSplats (
5462 centerCallback ?: ( index : number , x : number , y : number , z : number ) => void ,
5563 alphaCallback ?: ( index : number , alpha : number ) => void ,
5664 rgbCallback ?: ( index : number , r : number , g : number , b : number ) => void ,
@@ -74,14 +82,17 @@ export class SpzReader {
7482 sh3 ?: Float32Array ,
7583 ) => void ,
7684 ) {
85+ if ( ! this . headerParsed ) {
86+ throw new Error ( "SPZ file header must be parsed first" ) ;
87+ }
7788 if ( this . parsed ) {
7889 throw new Error ( "SPZ file already parsed" ) ;
7990 }
8091 this . parsed = true ;
8192
8293 if ( this . version === 1 ) {
8394 // float16 centers
84- const centerBytes = this . reader . read ( this . numSplats * 3 * 2 ) ;
95+ const centerBytes = await this . reader . read ( this . numSplats * 3 * 2 ) ;
8596 const centerUint16 = new Uint16Array ( centerBytes . buffer ) ;
8697 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
8798 const i3 = i * 3 ;
@@ -93,7 +104,7 @@ export class SpzReader {
93104 } else if ( this . version === 2 || this . version === 3 ) {
94105 // 24-bit fixed-point centers
95106 const fixed = 1 << this . fractionalBits ;
96- const centerBytes = this . reader . read ( this . numSplats * 3 * 3 ) ;
107+ const centerBytes = await this . reader . read ( this . numSplats * 3 * 3 ) ;
97108 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
98109 const i9 = i * 9 ;
99110 const x =
@@ -121,13 +132,13 @@ export class SpzReader {
121132 }
122133
123134 {
124- const bytes = this . reader . read ( this . numSplats ) ;
135+ const bytes = await this . reader . read ( this . numSplats ) ;
125136 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
126137 alphaCallback ?.( i , bytes [ i ] / 255 ) ;
127138 }
128139 }
129140 {
130- const rgbBytes = this . reader . read ( this . numSplats * 3 ) ;
141+ const rgbBytes = await this . reader . read ( this . numSplats * 3 ) ;
131142 const scale = SH_C0 / 0.15 ;
132143 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
133144 const i3 = i * 3 ;
@@ -138,7 +149,7 @@ export class SpzReader {
138149 }
139150 }
140151 {
141- const scalesBytes = this . reader . read ( this . numSplats * 3 ) ;
152+ const scalesBytes = await this . reader . read ( this . numSplats * 3 ) ;
142153 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
143154 const i3 = i * 3 ;
144155 const scaleX = Math . exp ( scalesBytes [ i3 ] / 16 - 10 ) ;
@@ -160,7 +171,7 @@ export class SpzReader {
160171 // v^2 + v^2 = 1
161172 // v = 1 / sqrt(2);
162173 const maxValue = 1 / Math . sqrt ( 2 ) ; // 0.7071
163- const quatBytes = this . reader . read ( this . numSplats * 4 ) ;
174+ const quatBytes = await this . reader . read ( this . numSplats * 4 ) ;
164175 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
165176 const i3 = i * 4 ;
166177 const quaternion = [ 0 , 0 , 0 , 0 ] ;
@@ -211,7 +222,7 @@ export class SpzReader {
211222 ) ;
212223 }
213224 } else {
214- const quatBytes = this . reader . read ( this . numSplats * 3 ) ;
225+ const quatBytes = await this . reader . read ( this . numSplats * 3 ) ;
215226 for ( let i = 0 ; i < this . numSplats ; i ++ ) {
216227 const i3 = i * 3 ;
217228 const quatX = quatBytes [ i3 ] / 127.5 - 1 ;
@@ -228,7 +239,7 @@ export class SpzReader {
228239 const sh1 = new Float32Array ( 3 * 3 ) ;
229240 const sh2 = this . shDegree >= 2 ? new Float32Array ( 5 * 3 ) : undefined ;
230241 const sh3 = this . shDegree >= 3 ? new Float32Array ( 7 * 3 ) : undefined ;
231- const shBytes = this . reader . read (
242+ const shBytes = await this . reader . read (
232243 this . numSplats * SH_DEGREE_TO_VECS [ this . shDegree ] * 3 ,
233244 ) ;
234245
@@ -592,6 +603,7 @@ export async function transcodeSpz(input: TranscodeSpzInput) {
592603 }
593604 case SplatFileType . SPZ : {
594605 const spz = new SpzReader ( { fileBytes : input . fileBytes } ) ;
606+ await spz . parseHeader ( ) ;
595607 const mapping = new Int32Array ( spz . numSplats ) ;
596608 mapping . fill ( - 1 ) ;
597609 const centers = new Float32Array ( spz . numSplats * 3 ) ;
0 commit comments