From 37ca147c53c89de9b656d4afff676611b23de788 Mon Sep 17 00:00:00 2001 From: Sandeep Nayathil <1101@trenser.com> Date: Thu, 2 Sep 2021 19:17:55 +0530 Subject: [PATCH 1/3] Corrected the clut lookup for the 4 channel color image pixel data for proper image rendering --- ...ixelDataToCanvasImageDataPseudocolorLUT.js | 43 ++++++++++++++++++- ...ataToCanvasImageDataPseudocolorLUT_test.js | 29 +++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js index 8f60b193..e2f494d0 100644 --- a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js +++ b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js @@ -35,7 +35,20 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co if (minPixelValue < 0) { while (storedPixelDataIndex < numPixels) { - grayscale = grayscaleLut[pixelData[storedPixelDataIndex++] + (-minPixelValue)]; + // Find the grayscale of 4 channels image data by calculating relative luminance value + if (image.color && ((image.width * image.height * 4) === numPixels)) { + const rValue = pixelData[storedPixelDataIndex++]; + const gValue = pixelData[storedPixelDataIndex++]; + const bValue = pixelData[storedPixelDataIndex++]; + + storedPixelDataIndex++; // The pixel data has 4 channels + + const luminance = getRelativeLuminance(rValue, gValue, bValue); + + grayscale = grayscaleLut[luminance + (-minPixelValue)]; + } else { + grayscale = grayscaleLut[pixelData[storedPixelDataIndex++] + (-minPixelValue)]; + } rgba = clut[grayscale]; canvasImageDataData[canvasImageDataIndex++] = rgba[0]; canvasImageDataData[canvasImageDataIndex++] = rgba[1]; @@ -44,7 +57,20 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co } } else { while (storedPixelDataIndex < numPixels) { - grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]]; + // Find the grayscale of 4 channels image data by calculating relative luminance value + if (image.color && ((image.width * image.height * 4) === numPixels)) { + const rValue = pixelData[storedPixelDataIndex++]; + const gValue = pixelData[storedPixelDataIndex++]; + const bValue = pixelData[storedPixelDataIndex++]; + + storedPixelDataIndex++; // The pixel data has 4 channels + + const luminance = getRelativeLuminance(rValue, gValue, bValue); + + grayscale = grayscaleLut[luminance]; + } else { + grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]]; + } rgba = clut[grayscale]; canvasImageDataData[canvasImageDataIndex++] = rgba[0]; canvasImageDataData[canvasImageDataIndex++] = rgba[1]; @@ -56,4 +82,17 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start; } +/** + * Calculates the relative luminance value from the RGB component values + * @param {Number} rValue R component value in RGB + * @param {Number} gValue G component value in RGB + * @param {Number} bValue B component value in RGB + * + * @returns {Number} The relative luminance value + */ +function getRelativeLuminance (rValue, gValue, bValue) { + // Calculate relative luminance can be calculated from linear RGB components + return Math.round(0.2126 * rValue + 0.7152 * gValue + 0.0722 * bValue); +} + export default storedPixelDataToCanvasImageDataPseudocolorLUT; diff --git a/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js b/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js index 4886637c..0e1be1c2 100644 --- a/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js +++ b/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js @@ -36,4 +36,33 @@ describe('storedPixelDataToCanvasImageDataPseudocolorLUT', function () { this.canvasImageData.should.be.deep.equal([4, 4, 1, 2, 7, 7, 2, 0]); }); + + describe('Color 4 Byte image', function () { + before(function () { + this.image.color = true; + this.grayscaleLut = [0, 1, 2, 3, 4, 5, 6, 7]; + this.colorLut = [[1, 2, 3, 4], [4, 4, 1, 2], [7, 7, 2, 0], [10, 10, 5, 6], [1, 2, 6, 5], [11, 11, 8, 9], [1, 2, 9, 8], [14, 14, 12, 13]]; + this.image.getPixelData = function () { + return [0, 1, 2, 3, 4, 5, 6, 7]; + }; + this.image.width = 2; + this.image.height = 1; + }); + + it('should get the values from colorLUT for color 4 byte image without the minPixel offset when minPixelValue == 0', function () { + this.image.minPixelValue = 0; + + storedPixelDataToCanvasImageDataPseudocolorLUT(this.image, this.grayscaleLut, this.colorLut, this.canvasImageData); + + this.canvasImageData.should.be.deep.equal([4, 4, 1, 2, 11, 11, 8, 9]); + }); + + it('should get the values from colorLUT for color 4 byte image with the minPixel offset when minPixelValue < 0', function () { + this.image.minPixelValue = -1; + + storedPixelDataToCanvasImageDataPseudocolorLUT(this.image, this.grayscaleLut, this.colorLut, this.canvasImageData); + + this.canvasImageData.should.be.deep.equal([7, 7, 2, 0, 1, 2, 9, 8]); + }); + }); }); From dd1d2367099ce106e1f00ab32cca649592d9e0d9 Mon Sep 17 00:00:00 2001 From: Sandeep N Date: Mon, 13 Sep 2021 23:12:24 +0530 Subject: [PATCH 2/3] Moved the clut lookup for the 4 channel color image pixel data to separate path for improving the performance --- ...ixelDataToCanvasImageDataPseudocolorLUT.js | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js index e2f494d0..06596e83 100644 --- a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js +++ b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js @@ -33,10 +33,10 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co clut = colorLut; } - if (minPixelValue < 0) { - while (storedPixelDataIndex < numPixels) { - // Find the grayscale of 4 channels image data by calculating relative luminance value - if (image.color && ((image.width * image.height * 4) === numPixels)) { + // Find the grayscale of 4 channels image data by calculating relative luminance value + if (image.color && ((image.width * image.height * 4) === numPixels)) { + if (minPixelValue < 0) { + while (storedPixelDataIndex < numPixels) { const rValue = pixelData[storedPixelDataIndex++]; const gValue = pixelData[storedPixelDataIndex++]; const bValue = pixelData[storedPixelDataIndex++]; @@ -46,19 +46,14 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co const luminance = getRelativeLuminance(rValue, gValue, bValue); grayscale = grayscaleLut[luminance + (-minPixelValue)]; - } else { - grayscale = grayscaleLut[pixelData[storedPixelDataIndex++] + (-minPixelValue)]; + rgba = clut[grayscale]; + canvasImageDataData[canvasImageDataIndex++] = rgba[0]; + canvasImageDataData[canvasImageDataIndex++] = rgba[1]; + canvasImageDataData[canvasImageDataIndex++] = rgba[2]; + canvasImageDataData[canvasImageDataIndex++] = rgba[3]; } - rgba = clut[grayscale]; - canvasImageDataData[canvasImageDataIndex++] = rgba[0]; - canvasImageDataData[canvasImageDataIndex++] = rgba[1]; - canvasImageDataData[canvasImageDataIndex++] = rgba[2]; - canvasImageDataData[canvasImageDataIndex++] = rgba[3]; - } - } else { - while (storedPixelDataIndex < numPixels) { - // Find the grayscale of 4 channels image data by calculating relative luminance value - if (image.color && ((image.width * image.height * 4) === numPixels)) { + } else { + while (storedPixelDataIndex < numPixels) { const rValue = pixelData[storedPixelDataIndex++]; const gValue = pixelData[storedPixelDataIndex++]; const bValue = pixelData[storedPixelDataIndex++]; @@ -68,9 +63,25 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co const luminance = getRelativeLuminance(rValue, gValue, bValue); grayscale = grayscaleLut[luminance]; - } else { - grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]]; + rgba = clut[grayscale]; + canvasImageDataData[canvasImageDataIndex++] = rgba[0]; + canvasImageDataData[canvasImageDataIndex++] = rgba[1]; + canvasImageDataData[canvasImageDataIndex++] = rgba[2]; + canvasImageDataData[canvasImageDataIndex++] = rgba[3]; } + } + } else if (minPixelValue < 0) { + while (storedPixelDataIndex < numPixels) { + grayscale = grayscaleLut[pixelData[storedPixelDataIndex++] + (-minPixelValue)]; + rgba = clut[grayscale]; + canvasImageDataData[canvasImageDataIndex++] = rgba[0]; + canvasImageDataData[canvasImageDataIndex++] = rgba[1]; + canvasImageDataData[canvasImageDataIndex++] = rgba[2]; + canvasImageDataData[canvasImageDataIndex++] = rgba[3]; + } + } else { + while (storedPixelDataIndex < numPixels) { + grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]]; rgba = clut[grayscale]; canvasImageDataData[canvasImageDataIndex++] = rgba[0]; canvasImageDataData[canvasImageDataIndex++] = rgba[1]; From 470d66ea16c47565149bfbb39ca77f82584f6b21 Mon Sep 17 00:00:00 2001 From: Sandeep N Date: Fri, 24 Sep 2021 12:46:15 +0530 Subject: [PATCH 3/3] Minor update to trigger pipeline rerun --- src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js index 06596e83..dafb7b57 100644 --- a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js +++ b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js @@ -33,7 +33,7 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co clut = colorLut; } - // Find the grayscale of 4 channels image data by calculating relative luminance value + // Finds the grayscale of 4 channels color image data by calculating the relative luminance value if (image.color && ((image.width * image.height * 4) === numPixels)) { if (minPixelValue < 0) { while (storedPixelDataIndex < numPixels) {