123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- 'use strict';
- var interlaceUtils = require('./interlace');
- var pixelBppMapper = [
- // 0 - dummy entry
- function() {},
- // 1 - L
- // 0: 0, 1: 0, 2: 0, 3: 0xff
- function(pxData, data, pxPos, rawPos) {
- if (rawPos === data.length) {
- throw new Error('Ran out of data');
- }
- var pixel = data[rawPos];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = 0xff;
- },
- // 2 - LA
- // 0: 0, 1: 0, 2: 0, 3: 1
- function(pxData, data, pxPos, rawPos) {
- if (rawPos + 1 >= data.length) {
- throw new Error('Ran out of data');
- }
- var pixel = data[rawPos];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = data[rawPos + 1];
- },
- // 3 - RGB
- // 0: 0, 1: 1, 2: 2, 3: 0xff
- function(pxData, data, pxPos, rawPos) {
- if (rawPos + 2 >= data.length) {
- throw new Error('Ran out of data');
- }
- pxData[pxPos] = data[rawPos];
- pxData[pxPos + 1] = data[rawPos + 1];
- pxData[pxPos + 2] = data[rawPos + 2];
- pxData[pxPos + 3] = 0xff;
- },
- // 4 - RGBA
- // 0: 0, 1: 1, 2: 2, 3: 3
- function(pxData, data, pxPos, rawPos) {
- if (rawPos + 3 >= data.length) {
- throw new Error('Ran out of data');
- }
- pxData[pxPos] = data[rawPos];
- pxData[pxPos + 1] = data[rawPos + 1];
- pxData[pxPos + 2] = data[rawPos + 2];
- pxData[pxPos + 3] = data[rawPos + 3];
- }
- ];
- var pixelBppCustomMapper = [
- // 0 - dummy entry
- function() {},
- // 1 - L
- // 0: 0, 1: 0, 2: 0, 3: 0xff
- function(pxData, pixelData, pxPos, maxBit) {
- var pixel = pixelData[0];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = maxBit;
- },
- // 2 - LA
- // 0: 0, 1: 0, 2: 0, 3: 1
- function(pxData, pixelData, pxPos) {
- var pixel = pixelData[0];
- pxData[pxPos] = pixel;
- pxData[pxPos + 1] = pixel;
- pxData[pxPos + 2] = pixel;
- pxData[pxPos + 3] = pixelData[1];
- },
- // 3 - RGB
- // 0: 0, 1: 1, 2: 2, 3: 0xff
- function(pxData, pixelData, pxPos, maxBit) {
- pxData[pxPos] = pixelData[0];
- pxData[pxPos + 1] = pixelData[1];
- pxData[pxPos + 2] = pixelData[2];
- pxData[pxPos + 3] = maxBit;
- },
- // 4 - RGBA
- // 0: 0, 1: 1, 2: 2, 3: 3
- function(pxData, pixelData, pxPos) {
- pxData[pxPos] = pixelData[0];
- pxData[pxPos + 1] = pixelData[1];
- pxData[pxPos + 2] = pixelData[2];
- pxData[pxPos + 3] = pixelData[3];
- }
- ];
- function bitRetriever(data, depth) {
- var leftOver = [];
- var i = 0;
- function split() {
- if (i === data.length) {
- throw new Error('Ran out of data');
- }
- var byte = data[i];
- i++;
- var byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1;
- switch (depth) {
- default:
- throw new Error('unrecognised depth');
- case 16:
- byte2 = data[i];
- i++;
- leftOver.push(((byte << 8) + byte2));
- break;
- case 4:
- byte2 = byte & 0x0f;
- byte1 = byte >> 4;
- leftOver.push(byte1, byte2);
- break;
- case 2:
- byte4 = byte & 3;
- byte3 = byte >> 2 & 3;
- byte2 = byte >> 4 & 3;
- byte1 = byte >> 6 & 3;
- leftOver.push(byte1, byte2, byte3, byte4);
- break;
- case 1:
- byte8 = byte & 1;
- byte7 = byte >> 1 & 1;
- byte6 = byte >> 2 & 1;
- byte5 = byte >> 3 & 1;
- byte4 = byte >> 4 & 1;
- byte3 = byte >> 5 & 1;
- byte2 = byte >> 6 & 1;
- byte1 = byte >> 7 & 1;
- leftOver.push(byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8);
- break;
- }
- }
- return {
- get: function(count) {
- while (leftOver.length < count) {
- split();
- }
- var returner = leftOver.slice(0, count);
- leftOver = leftOver.slice(count);
- return returner;
- },
- resetAfterLine: function() {
- leftOver.length = 0;
- },
- end: function() {
- if (i !== data.length) {
- throw new Error('extra data found');
- }
- }
- };
- }
- function mapImage8Bit(image, pxData, getPxPos, bpp, data, rawPos) { // eslint-disable-line max-params
- var imageWidth = image.width;
- var imageHeight = image.height;
- var imagePass = image.index;
- for (var y = 0; y < imageHeight; y++) {
- for (var x = 0; x < imageWidth; x++) {
- var pxPos = getPxPos(x, y, imagePass);
- pixelBppMapper[bpp](pxData, data, pxPos, rawPos);
- rawPos += bpp; //eslint-disable-line no-param-reassign
- }
- }
- return rawPos;
- }
- function mapImageCustomBit(image, pxData, getPxPos, bpp, bits, maxBit) { // eslint-disable-line max-params
- var imageWidth = image.width;
- var imageHeight = image.height;
- var imagePass = image.index;
- for (var y = 0; y < imageHeight; y++) {
- for (var x = 0; x < imageWidth; x++) {
- var pixelData = bits.get(bpp);
- var pxPos = getPxPos(x, y, imagePass);
- pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
- }
- bits.resetAfterLine();
- }
- }
- exports.dataToBitMap = function(data, bitmapInfo) {
- var width = bitmapInfo.width;
- var height = bitmapInfo.height;
- var depth = bitmapInfo.depth;
- var bpp = bitmapInfo.bpp;
- var interlace = bitmapInfo.interlace;
- if (depth !== 8) {
- var bits = bitRetriever(data, depth);
- }
- var pxData;
- if (depth <= 8) {
- pxData = new Buffer(width * height * 4);
- }
- else {
- pxData = new Uint16Array(width * height * 4);
- }
- var maxBit = Math.pow(2, depth) - 1;
- var rawPos = 0;
- var images;
- var getPxPos;
- if (interlace) {
- images = interlaceUtils.getImagePasses(width, height);
- getPxPos = interlaceUtils.getInterlaceIterator(width, height);
- }
- else {
- var nonInterlacedPxPos = 0;
- getPxPos = function() {
- var returner = nonInterlacedPxPos;
- nonInterlacedPxPos += 4;
- return returner;
- };
- images = [{ width: width, height: height }];
- }
- for (var imageIndex = 0; imageIndex < images.length; imageIndex++) {
- if (depth === 8) {
- rawPos = mapImage8Bit(images[imageIndex], pxData, getPxPos, bpp, data, rawPos);
- }
- else {
- mapImageCustomBit(images[imageIndex], pxData, getPxPos, bpp, bits, maxBit);
- }
- }
- if (depth === 8) {
- if (rawPos !== data.length) {
- throw new Error('extra data found');
- }
- }
- else {
- bits.end();
- }
- return pxData;
- };
|