All files index.js

100% Statements 32/32
83.33% Branches 5/6
100% Functions 5/5
100% Lines 32/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121                  2x 2x 2x   2x                 1x 1x 1x 1x 1x   1x                           1x                             1x 1x 1x     1x     1x   1x 1x     1x   4x   4x 1x       4x           4x   4x           4x           4x   4x 1x                           1x 1x 1x  
import workerize from 'workerize';
 
/**
 * It returns a canvas with the given width and height
 * @param {Number} w - width
 * @param {Number} h - height
 * @returns {Object}
 */
function getCanvas(w, h) {
    const canvas = document.createElement('canvas');
    canvas.width = w;
    canvas.height = h;
 
    return canvas;
}
 
/**
 * Given a ImageData it returns the dataURL
 * @param {ImageData} imageData
 * @returns {String}
 */
function convertImageDataToCanvasURL(imageData) {
    const canvas = window.document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = imageData.width;
    canvas.height = imageData.height;
    ctx.putImageData(imageData, 0, 0);
 
    return canvas.toDataURL();
}
 
/**
 * Given a worker file with the transformation the work is split
 * between the configured number of workers and the transformation is applied
 * returning a Promise
 * @param {Object} data - image data
 * @param {Function} transform - transformation function
 * @param {Object} options - object to be passed to the transform function
 * @param {Number} nWorkers - number of workers to transform the image
 * @returns {Promise}
 */
function applyFilter({ data, transform, options, nWorkers }) {
    const worker = workerize(`
        var transform = ${transform};
 
        export function execute(canvas, index, length, options) {
            canvas.data = transform({ 
                data: canvas.data, 
                length: length, 
                options: options
            });
 
            return { result: canvas, index: index };
        }
    `);
 
    // Drawing the source image into the target canvas
    const canvas = getCanvas(data.width, data.height);
    const context = canvas.getContext('2d');
    context.putImageData(data, 0, 0);
 
    // Minimium 1 worker
    nWorkers = nWorkers || 1;
 
    // Height of the picture chunck for every worker
    const blockSize = Math.floor(canvas.height / nWorkers);
 
    return new Promise(resolve => {
        let finished = 0;
        let height;
 
        for (let index = 0; index < nWorkers; index++) {
            // In the last worker we have to make sure we process whatever is missing
            height = blockSize;
 
            if (index + 1 === nWorkers) {
                height = canvas.height - blockSize * index;
            }
 
            // Getting the picture
            const canvasData = context.getImageData(
                0,
                blockSize * index,
                canvas.width,
                height
            );
            const length = height * canvas.width * 4;
 
            worker
                .execute(canvasData, index, length, options)
                .then(response => {
                    // Copying back canvas data to canvas
                    // If the first webworker  (index 0) returns data, apply it at pixel (0, 0) onwards
                    // If the second webworker  (index 1) returns data, apply it at pixel (0, canvas.height/4) onwards, and so on
                    context.putImageData(
                        response.result,
                        0,
                        blockSize * response.index
                    );
 
                    finished++;
 
                    if (finished === nWorkers) {
                        resolve(
                            context.getImageData(
                                0,
                                0,
                                canvas.width,
                                canvas.height
                            )
                        );
                    }
                });
        }
    });
}
 
exports.getCanvas = getCanvas;
exports.convertImageDataToCanvasURL = convertImageDataToCanvasURL;
exports.applyFilter = applyFilter;