点群PNGではRGBから整数、整数からRGB、それぞれ2ピクセル分まで考慮しての変換ルーチンが必要になる。スクリプトを適当に作って間違えないよう関数をまとめておく。
//1ピクセル分rgbを符号なし整数に変換[0, 2^24-1]
/*
@param typed : Uint8ClampedArray with 3 elements
@return number : number
*/
const rgbToUnsigned = ( value ) => {
return value[0] * 256 ** 2
+ value[1] * 256 ** 1
+ value[2] * 256 ** 0;
};
//1ピクセル分rgbを符号付き整数に変換[-2^23, 2^23-1]
/*
@param typed : Uint8ClampedArray with 3 elements
@return number : number
*/
const rgbToSigned = ( value ) => {
return rgbToUnsigned( value )
- ( value[0] < 128 ? 0 : 256 ** 3 );
};
//2ピクセル分rgbを符号なし整数に変換[0, 2^48-1]
/*
@param typed : Uint8ClampedArray with 6 elements
@return number : number
*/
const rgb2pxToUnsigned = ( value ) => {
return value[0] * 256 ** 5
+ value[1] * 256 ** 4
+ value[2] * 256 ** 3
+ value[3] * 256 ** 2
+ value[4] * 256 ** 1
+ value[5] * 256 ** 0;
};
//2ピクセル分rgbを符号付き整数に変換[-2^47, 2^47-1]
/*
@param typed : Uint8ClampedArray with 6 elements
@return number : number
*/
const rgb2pxToSigned = ( value ) => {
return rgb2pxToUnsigned( value )
- ( value[0] < 128 ? 0 : 256 ** 6 );
};
//整数を1ピクセル分rgbに変換
/*
@param number : number
@return array : array uint8clamped with 3 elements
*/
const numberToRgb = ( value ) => {
return [
value >> 16 & 0xff,
value >> 8 & 0xff,
value & 0xff,
];
};
//整数を2ピクセル分rgbに変換
/*
@param number : number
@return array : array uint8clamped with 3 elements
*/
const numberToRgb2px = ( value ) => {
const number24 = 256 ** 3;
const upper = ( value - (value % number24) ) / number24
- ( value < 0 ? 1 : 0 );
return [].concat( numberToRgb(upper), numberToRgb(value) );
};
JavaScriptのビット演算は数値を32ビットとして扱うので、2ピクセル分RGB(48ビット)を正しく扱えず、一工夫が必要だった。