Skip to content

Commit

Permalink
ColorManagement: Support treeshake. (#29816)
Browse files Browse the repository at this point in the history
* ColorManagement: Support treeshake.

* clean up
  • Loading branch information
linbingquan authored Nov 6, 2024
1 parent f2d69d1 commit d82b592
Showing 1 changed file with 130 additions and 122 deletions.
252 changes: 130 additions & 122 deletions src/math/ColorManagement.js
Original file line number Diff line number Diff line change
@@ -1,182 +1,190 @@
import { SRGBColorSpace, LinearSRGBColorSpace, SRGBTransfer, LinearTransfer, NoColorSpace } from '../constants.js';
import { Matrix3 } from './Matrix3.js';

export const ColorManagement = {

enabled: true,

workingColorSpace: LinearSRGBColorSpace,

/**
* Implementations of supported color spaces.
*
* Required:
* - primaries: chromaticity coordinates [ rx ry gx gy bx by ]
* - whitePoint: reference white [ x y ]
* - transfer: transfer function (pre-defined)
* - toXYZ: Matrix3 RGB to XYZ transform
* - fromXYZ: Matrix3 XYZ to RGB transform
* - luminanceCoefficients: RGB luminance coefficients
*
* Optional:
* - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }
* - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
*
* Reference:
* - https://www.russellcottrell.com/photo/matrixCalculator.htm
*/
spaces: {},
const LINEAR_REC709_TO_XYZ = /*@__PURE__*/ new Matrix3().set(
0.4123908, 0.3575843, 0.1804808,
0.2126390, 0.7151687, 0.0721923,
0.0193308, 0.1191948, 0.9505322
);

convert: function ( color, sourceColorSpace, targetColorSpace ) {
const XYZ_TO_LINEAR_REC709 = /*@__PURE__*/ new Matrix3().set(
3.2409699, - 1.5373832, - 0.4986108,
- 0.9692436, 1.8759675, 0.0415551,
0.0556301, - 0.2039770, 1.0569715
);

if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {
function createColorManagement() {

return color;
const ColorManagement = {

}
enabled: true,

if ( this.spaces[ sourceColorSpace ].transfer === SRGBTransfer ) {
workingColorSpace: LinearSRGBColorSpace,

color.r = SRGBToLinear( color.r );
color.g = SRGBToLinear( color.g );
color.b = SRGBToLinear( color.b );
/**
* Implementations of supported color spaces.
*
* Required:
* - primaries: chromaticity coordinates [ rx ry gx gy bx by ]
* - whitePoint: reference white [ x y ]
* - transfer: transfer function (pre-defined)
* - toXYZ: Matrix3 RGB to XYZ transform
* - fromXYZ: Matrix3 XYZ to RGB transform
* - luminanceCoefficients: RGB luminance coefficients
*
* Optional:
* - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }
* - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
*
* Reference:
* - https://www.russellcottrell.com/photo/matrixCalculator.htm
*/
spaces: {},

}
convert: function ( color, sourceColorSpace, targetColorSpace ) {

if ( this.spaces[ sourceColorSpace ].primaries !== this.spaces[ targetColorSpace ].primaries ) {
if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {

color.applyMatrix3( this.spaces[ sourceColorSpace ].toXYZ );
color.applyMatrix3( this.spaces[ targetColorSpace ].fromXYZ );
return color;

}
}

if ( this.spaces[ targetColorSpace ].transfer === SRGBTransfer ) {
if ( this.spaces[ sourceColorSpace ].transfer === SRGBTransfer ) {

color.r = LinearToSRGB( color.r );
color.g = LinearToSRGB( color.g );
color.b = LinearToSRGB( color.b );
color.r = SRGBToLinear( color.r );
color.g = SRGBToLinear( color.g );
color.b = SRGBToLinear( color.b );

}
}

return color;
if ( this.spaces[ sourceColorSpace ].primaries !== this.spaces[ targetColorSpace ].primaries ) {

},
color.applyMatrix3( this.spaces[ sourceColorSpace ].toXYZ );
color.applyMatrix3( this.spaces[ targetColorSpace ].fromXYZ );

fromWorkingColorSpace: function ( color, targetColorSpace ) {
}

return this.convert( color, this.workingColorSpace, targetColorSpace );
if ( this.spaces[ targetColorSpace ].transfer === SRGBTransfer ) {

},
color.r = LinearToSRGB( color.r );
color.g = LinearToSRGB( color.g );
color.b = LinearToSRGB( color.b );

toWorkingColorSpace: function ( color, sourceColorSpace ) {
}

return this.convert( color, sourceColorSpace, this.workingColorSpace );
return color;

},
},

getPrimaries: function ( colorSpace ) {
fromWorkingColorSpace: function ( color, targetColorSpace ) {

return this.spaces[ colorSpace ].primaries;
return this.convert( color, this.workingColorSpace, targetColorSpace );

},
},

getTransfer: function ( colorSpace ) {
toWorkingColorSpace: function ( color, sourceColorSpace ) {

if ( colorSpace === NoColorSpace ) return LinearTransfer;
return this.convert( color, sourceColorSpace, this.workingColorSpace );

return this.spaces[ colorSpace ].transfer;
},

},
getPrimaries: function ( colorSpace ) {

getLuminanceCoefficients: function ( target, colorSpace = this.workingColorSpace ) {
return this.spaces[ colorSpace ].primaries;

return target.fromArray( this.spaces[ colorSpace ].luminanceCoefficients );
},

},
getTransfer: function ( colorSpace ) {

define: function ( colorSpaces ) {
if ( colorSpace === NoColorSpace ) return LinearTransfer;

Object.assign( this.spaces, colorSpaces );
return this.spaces[ colorSpace ].transfer;

},
},

// Internal APIs
getLuminanceCoefficients: function ( target, colorSpace = this.workingColorSpace ) {

_getMatrix: function ( targetMatrix, sourceColorSpace, targetColorSpace ) {
return target.fromArray( this.spaces[ colorSpace ].luminanceCoefficients );

return targetMatrix
.copy( this.spaces[ sourceColorSpace ].toXYZ )
.multiply( this.spaces[ targetColorSpace ].fromXYZ );
},

},
define: function ( colorSpaces ) {

_getDrawingBufferColorSpace: function ( colorSpace ) {
Object.assign( this.spaces, colorSpaces );

return this.spaces[ colorSpace ].outputColorSpaceConfig.drawingBufferColorSpace;
},

},
// Internal APIs

_getUnpackColorSpace: function ( colorSpace = this.workingColorSpace ) {
_getMatrix: function ( targetMatrix, sourceColorSpace, targetColorSpace ) {

return this.spaces[ colorSpace ].workingColorSpaceConfig.unpackColorSpace;
return targetMatrix
.copy( this.spaces[ sourceColorSpace ].toXYZ )
.multiply( this.spaces[ targetColorSpace ].fromXYZ );

}
},

};
_getDrawingBufferColorSpace: function ( colorSpace ) {

export function SRGBToLinear( c ) {
return this.spaces[ colorSpace ].outputColorSpaceConfig.drawingBufferColorSpace;

return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
},

}
_getUnpackColorSpace: function ( colorSpace = this.workingColorSpace ) {

export function LinearToSRGB( c ) {
return this.spaces[ colorSpace ].workingColorSpaceConfig.unpackColorSpace;

return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
}

};

/******************************************************************************
* sRGB definitions
*/

const REC709_PRIMARIES = [ 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 ];
const REC709_LUMINANCE_COEFFICIENTS = [ 0.2126, 0.7152, 0.0722 ];
const D65 = [ 0.3127, 0.3290 ];

ColorManagement.define( {

[ LinearSRGBColorSpace ]: {
primaries: REC709_PRIMARIES,
whitePoint: D65,
transfer: LinearTransfer,
toXYZ: LINEAR_REC709_TO_XYZ,
fromXYZ: XYZ_TO_LINEAR_REC709,
luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },
outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
},

[ SRGBColorSpace ]: {
primaries: REC709_PRIMARIES,
whitePoint: D65,
transfer: SRGBTransfer,
toXYZ: LINEAR_REC709_TO_XYZ,
fromXYZ: XYZ_TO_LINEAR_REC709,
luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
},

} );

return ColorManagement;

}

/******************************************************************************
* sRGB definitions
*/
export const ColorManagement = /*@__PURE__*/ createColorManagement();

const REC709_PRIMARIES = [ 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 ];
const REC709_LUMINANCE_COEFFICIENTS = [ 0.2126, 0.7152, 0.0722 ];
const D65 = [ 0.3127, 0.3290 ];
export function SRGBToLinear( c ) {

const LINEAR_REC709_TO_XYZ = /*@__PURE__*/ new Matrix3().set(
0.4123908, 0.3575843, 0.1804808,
0.2126390, 0.7151687, 0.0721923,
0.0193308, 0.1191948, 0.9505322
);
return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );

const XYZ_TO_LINEAR_REC709 = /*@__PURE__*/ new Matrix3().set(
3.2409699, - 1.5373832, - 0.4986108,
- 0.9692436, 1.8759675, 0.0415551,
0.0556301, - 0.2039770, 1.0569715
);
}

ColorManagement.define( {

[ LinearSRGBColorSpace ]: {
primaries: REC709_PRIMARIES,
whitePoint: D65,
transfer: LinearTransfer,
toXYZ: LINEAR_REC709_TO_XYZ,
fromXYZ: XYZ_TO_LINEAR_REC709,
luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },
outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
},

[ SRGBColorSpace ]: {
primaries: REC709_PRIMARIES,
whitePoint: D65,
transfer: SRGBTransfer,
toXYZ: LINEAR_REC709_TO_XYZ,
fromXYZ: XYZ_TO_LINEAR_REC709,
luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
},

} );
export function LinearToSRGB( c ) {

return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;

}

0 comments on commit d82b592

Please sign in to comment.