Skip to content

Commit

Permalink
Update PGMLoader, add support for P2
Browse files Browse the repository at this point in the history
  • Loading branch information
gkjohnson committed Sep 17, 2022
1 parent 2fb75be commit d9b1f9d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 31 deletions.
28 changes: 21 additions & 7 deletions src/pgm-loader/PGMLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {
UnsignedByteType,
HalfFloatType,
sRGBEncoding,
LuminanceFormat,
LinearFilter,
LinearMipMapLinearFilter,
RGBAFormat,
LinearEncoding,
} from 'three';

/**
Expand Down Expand Up @@ -35,27 +36,28 @@ export class PGMLoader extends PGMLoaderBase {
* the function the data is applied to it.
* @param {String} url
* @param {DataTexture} texture
* @returns {DataTexture}
* @returns {Promise<DataTexture>}
*/
load( url, texture = new DataTexture() ) {

const manager = this.manager;
manager.itemStart( url );
super.load( url ).then( result => {
return super.load( url ).then( result => {

texture.copy( result );
texture.needsUpdate = true;
return texture;

} ).catch( err => {

manager.itemError( url, err );
throw err;

} ).finally( () => {

manager.itemEnd( url );

} );
return texture;

}

Expand All @@ -75,15 +77,27 @@ export class PGMLoader extends PGMLoaderBase {

}

const data = result.data;
const rgbaBuffer = new data.constructor( data.length * 4 );
for ( let i = 0, l = data.length; i < l; i ++ ) {

const v = data[ i ];
rgbaBuffer[ i * 4 + 0 ] = v;
rgbaBuffer[ i * 4 + 1 ] = v;
rgbaBuffer[ i * 4 + 2 ] = v;
rgbaBuffer[ i * 4 + 3 ] = 1;

}

// TODO: if type if HalfFloatType then do the values need to be normalized by maxValue?
texture.image.width = result.width;
texture.image.height = result.height;
texture.image.data = result.data;
texture.image.data = rgbaBuffer;
texture.minFilter = LinearMipMapLinearFilter;
texture.magFilter = LinearFilter;
texture.type = result.data.BYTES_PER_ELEMENT === 1 ? UnsignedByteType : HalfFloatType;
texture.encoding = sRGBEncoding;
texture.format = LuminanceFormat;
texture.encoding = result.data.BYTES_PER_ELEMENT === 1 ? sRGBEncoding : LinearEncoding;
texture.format = RGBAFormat;
texture.flipY = true;
texture.generateMipmaps = true;
texture.needsUpdate = true;
Expand Down
72 changes: 49 additions & 23 deletions src/pgm-loader/PGMLoaderBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ export class PGMLoaderBase {
}

// check file identifier
if ( readString( 2 ) !== 'P5' ) {
const identifier = readString( 2 );
if ( identifier !== 'P5' && identifier !== 'P2' ) {

throw new Error( 'PGMLoader: Invalid file identifier' );

Expand All @@ -134,18 +135,27 @@ export class PGMLoaderBase {

for ( let i = 0; i < MAX_ITERATIONS; i ++ ) {

header += readStringUntil( c => /[\s\n\r]/g.test( c ) );
header += readString( 1 );
const readContent = readStringUntil( c => /[\s\n\r#]/g.test( c ) );
header += readContent;

headerTokens = header
const delineator = readString( 1 );
if ( delineator === '#' ) {

// comment
readStringUntil( c => /[\n\r]/g.test( c ) );

} else {

header += delineator;

}

// remove comments
.replace( /#[^\n\r]*[\n\r]/g, '' )
headerTokens = header

// tokenize
// tokenize
.split( /\s+/g )

// remove empty tokens
// remove empty tokens
.filter( t => !! t );

if ( headerTokens.length === 3 ) {
Expand All @@ -166,31 +176,47 @@ export class PGMLoaderBase {
const height = parseInt( headerTokens[ 1 ] );
const maxValue = parseInt( headerTokens[ 2 ] );
const byteLen = maxValue < 256 ? 1 : 2;
let data;

if ( width * height * byteLen !== buffer.byteLength - currIndex ) {
if ( identifier === 'P5' ) {

throw new Error( 'PGMLoader: Invalid data length' );
if ( width * height * byteLen !== buffer.byteLength - currIndex ) {

}
throw new Error( 'PGMLoader: Invalid data length' );

let data;
if ( byteLen === 1 ) {
}

if ( byteLen === 1 ) {

data = new Uint8Array( buffer, currIndex, width * height );

} else {

// Uint16Array cannot have an offset index that is not a
// multiple of 2 so copy the data buffer here to its own
// separate buffer
const dataBuffer = buffer.slice( currIndex, currIndex + width * height * 2 );

data = new Uint8Array( buffer, currIndex, width * height );
// TODO: Handle endianness properly. We can't guarantee what the byte order of the file is
// or what the byte order of the javascript platform is.
// The expected endianness is flipped
swapByteOrder( dataBuffer );

data = new Uint16Array( dataBuffer );

}

} else {

// Uint16Array cannot have an offset index that is not a
// multiple of 2 so copy the data buffer here to its own
// separate buffer
const dataBuffer = buffer.slice( currIndex, currIndex + width * height * 2 );
data = byteLen === 1 ? new Uint8Array( width * height ) : Uint16Array( width * height );

// TODO: Handle endianness properly. We can't guarantee what the byte order of the file is
// or what the byte order of the javascript platform is.
// The expected endianness is flipped
swapByteOrder( dataBuffer );
const remainingContent = readString( buffer.byteLength - currIndex );
const parsed = remainingContent.split( /[\s\n\r]+/g );
for ( let i = 0, l = width * height; i < l; i ++ ) {

data = new Uint16Array( dataBuffer );
data[ i ] = parseFloat( parsed[ i ] );

}

}

Expand Down
2 changes: 1 addition & 1 deletion src/pgm-loader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ constructor( manager : LoadingManager = DefaultLoadingManager ) : void
### .load

```js
load( url : String, texture : DataTexture = new DataTexture() ) : DataTexture
load( url : String, texture : DataTexture = new DataTexture() ) : Promise<DataTexture>
```

Loads and parses the PGM file and returns a DataTexture. If a DataTexture is passed into
Expand Down

0 comments on commit d9b1f9d

Please sign in to comment.