Code coverage report for lib\bitmapper.js

Statements: 95.6% (87 / 91)      Branches: 90.32% (28 / 31)      Functions: 100% (7 / 7)      Lines: 95.6% (87 / 91)      Ignored: none     

All files » lib/ » bitmapper.js
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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 1641   1   217 217 1 202091 1   202090 202090 202090         149504 149504 149504 149504   48460 48460 48460 48460   2904 2904 2904 2904 2904 2904   1222 1222 1222 1222 1222 1222 1222 1222 1222 1222     217   184229 202091   184228 184228 184228     7018     205             1   336 217   336 336 259     77   325 325 325 325 325   325 70 70   255 255 370259 370259 370259   255     325 717 717 717 717 11484 429094 184229   429093   429093 1716369 1716369 979457 1   979456   736912       429092   11482 7018       323 118       205     323     1                                                  
var interlaceUtils = require('./interlace');
 
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++;
    switch(depth) {
      default:
        throw new Error("unrecognised depth");
        break;
      case 16:
        var byte2 = data[i];
        i++;
        leftOver.push(((byte << 8) + byte2));
        break;
      case 4:
        var byte2 = byte & 0x0f;
        var byte1 = byte >> 4;
        leftOver.push(byte1, byte2);
        break;
      case 2:
        var byte4 = byte & 3;
        var byte3 = byte >> 2 & 3;
        var byte2 = byte >> 4 & 3;
        var byte1 = byte >> 6 & 3;
        leftOver.push(byte1, byte2, byte3, byte4);
        break;
      case 1:
        var byte8 = byte & 1;
        var byte7 = byte >> 1 & 1;
        var byte6 = byte >> 2 & 1;
        var byte5 = byte >> 3 & 1;
        var byte4 = byte >> 4 & 1;
        var byte3 = byte >> 5 & 1;
        var byte2 = byte >> 6 & 1;
        var 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() {
      Iif (i !== data.length) {
        throw new Error("extra data found");
      }
    }
  };
}
 
exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) {
 
  if (depth !== 8) {
    var bits = bitRetriever(data, depth);
  }
  var pxData;
  if (depth <= 8) {
    pxData = new Buffer(width * height * 4);
  } else {
    // TODO: could be more effecient and use a buffer but change how we write to use 16 bit write methods with index * 2
    pxData = new Array(width * height * 4);
  }
  var maxBit = Math.pow(2, depth) - 1;
  var rawPos = 0;
  var pixelData;
  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++) {
    var imageWidth = images[imageIndex].width;
    var imageHeight = images[imageIndex].height;
    var imagePass = images[imageIndex].index;
    for (var y = 0; y < imageHeight; y++) {
      for (var x = 0; x < imageWidth; x++) {
        if (depth !== 8) {
          pixelData = bits.get(bpp);
        }
        var pxPos = getPxPos(x, y, imagePass);
        //console.log(x,y,imageIndex, pxPos);
        for (var i = 0; i < 4; i++) {
          var idx = pixelBppMap[bpp][i];
          if (depth === 8) {
            if (i === data.length) {
              throw new Error("Ran out of data");
            }
            pxData[pxPos + i] = idx !== 0xff ? data[idx + rawPos] : maxBit;
          } else {
            pxData[pxPos + i] = idx !== 0xff ? pixelData[idx] : maxBit;
          }
        }
        //console.log("R", pxData[pxPos], "G", pxData[pxPos + 1], "B", pxData[pxPos + 2], "A", pxData[pxPos + 3]);
        rawPos += bpp;
      }
      if (depth !== 8) {
        bits.resetAfterLine();
      }
    }
  }
  if (depth === 8) {
    Iif (rawPos !== data.length) {
      throw new Error("extra data found");
    }
  } else {
    bits.end();
  }
 
  return pxData;
};
 
var pixelBppMap = {
  1: { // L
    0: 0,
    1: 0,
    2: 0,
    3: 0xff
  },
  2: { // LA
    0: 0,
    1: 0,
    2: 0,
    3: 1
  },
  3: { // RGB
    0: 0,
    1: 1,
    2: 2,
    3: 0xff
  },
  4: { // RGBA
    0: 0,
    1: 1,
    2: 2,
    3: 3
  }
};