Skip to content

Commit

Permalink
Merge pull request #15 from senzil/bmp-negative-height#14
Browse files Browse the repository at this point in the history
added support for negative height in header (top-down bmp)
  • Loading branch information
shaozilee authored Oct 23, 2017
2 parents 155aa62 + ca7cd09 commit 832bcbc
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
.idea
33 changes: 23 additions & 10 deletions lib/decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function BmpDecoder(buffer,is_with_alpha) {
this.pos = 0;
this.buffer = buffer;
this.is_with_alpha = !!is_with_alpha;
this.bottom_up = true;
this.flag = this.buffer.toString("utf-8", 0, this.pos += 2);
if (this.flag != "BM") throw new Error("Invalid BMP File");
this.parseHeader();
Expand All @@ -26,7 +27,7 @@ BmpDecoder.prototype.parseHeader = function() {
this.pos += 4;
this.width = this.buffer.readUInt32LE(this.pos);
this.pos += 4;
this.height = this.buffer.readUInt32LE(this.pos);
this.height = this.buffer.readInt32LE(this.pos);
this.pos += 4;
this.planes = this.buffer.readUInt16LE(this.pos);
this.pos += 2;
Expand All @@ -47,7 +48,7 @@ BmpDecoder.prototype.parseHeader = function() {

if(this.bitPP === 16 && this.is_with_alpha){
this.bitPP = 15
};
}
if (this.bitPP < 15) {
var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
this.palette = new Array(len);
Expand All @@ -64,6 +65,10 @@ BmpDecoder.prototype.parseHeader = function() {
};
}
}
if(this.height < 0) {
this.height *= -1;
this.bottom_up = false;
}

}

Expand All @@ -84,10 +89,12 @@ BmpDecoder.prototype.parseBGR = function() {
BmpDecoder.prototype.bit1 = function() {
var xlen = Math.ceil(this.width / 8);
var mode = xlen%4;
var y = this.height >= 0 ? this.height - 1 : -this.height
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < xlen; x++) {
var b = this.buffer.readUInt8(this.pos++);
var location = y * this.width * 4 + x*8*4;
var location = line * this.width * 4 + x*8*4;
for (var i = 0; i < 8; i++) {
if(x*8+i<this.width){
var rgb = this.palette[((b>>(7-i))&0x1)];
Expand All @@ -111,9 +118,10 @@ BmpDecoder.prototype.bit4 = function() {
var xlen = Math.ceil(this.width/2);
var mode = xlen%4;
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < xlen; x++) {
var b = this.buffer.readUInt8(this.pos++);
var location = y * this.width * 4 + x*2*4;
var location = line * this.width * 4 + x*2*4;

var before = b>>4;
var after = b&0x0F;
Expand Down Expand Up @@ -143,9 +151,10 @@ BmpDecoder.prototype.bit4 = function() {
BmpDecoder.prototype.bit8 = function() {
var mode = this.width%4;
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < this.width; x++) {
var b = this.buffer.readUInt8(this.pos++);
var location = y * this.width * 4 + x*4;
var location = line * this.width * 4 + x*4;
if(b < this.palette.length) {
var rgb = this.palette[b];
this.data[location] = rgb.blue;
Expand All @@ -169,6 +178,7 @@ BmpDecoder.prototype.bit15 = function() {
var dif_w =this.width % 3;
var _11111 = parseInt("11111", 2),_1_5 = _11111;
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < this.width; x++) {

var B = this.buffer.readUInt16LE(this.pos);
Expand All @@ -178,7 +188,7 @@ BmpDecoder.prototype.bit15 = function() {
var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;
var alpha = (B>>15)?0xFF:0x00;

var location = y * this.width * 4 + x * 4;
var location = line * this.width * 4 + x * 4;
this.data[location] = red;
this.data[location + 1] = green;
this.data[location + 2] = blue;
Expand All @@ -194,6 +204,7 @@ BmpDecoder.prototype.bit16 = function() {
var _11111 = parseInt("11111", 2),_1_5 = _11111;
var _111111 = parseInt("111111", 2),_1_6 = _111111;
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < this.width; x++) {

var B = this.buffer.readUInt16LE(this.pos);
Expand All @@ -203,7 +214,7 @@ BmpDecoder.prototype.bit16 = function() {
var green = (B >> 5 & _1_6 ) / _1_6 * 255 | 0;
var red = (B >> 11) / _1_5 * 255 | 0;

var location = y * this.width * 4 + x * 4;
var location = line * this.width * 4 + x * 4;
this.data[location] = red;
this.data[location + 1] = green;
this.data[location + 2] = blue;
Expand All @@ -217,11 +228,12 @@ BmpDecoder.prototype.bit16 = function() {
BmpDecoder.prototype.bit24 = function() {
//when height > 0
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < this.width; x++) {
var blue = this.buffer.readUInt8(this.pos++);
var green = this.buffer.readUInt8(this.pos++);
var red = this.buffer.readUInt8(this.pos++);
var location = y * this.width * 4 + x * 4;
var location = line * this.width * 4 + x * 4;
this.data[location] = red;
this.data[location + 1] = green;
this.data[location + 2] = blue;
Expand All @@ -234,18 +246,19 @@ BmpDecoder.prototype.bit24 = function() {
};

/**
* add 32bit decode func
* add 32bit decode func
* @author soubok
*/
BmpDecoder.prototype.bit32 = function() {
//when height > 0
for (var y = this.height - 1; y >= 0; y--) {
var line = this.bottom_up ? y : this.height - 1 - y
for (var x = 0; x < this.width; x++) {
var blue = this.buffer.readUInt8(this.pos++);
var green = this.buffer.readUInt8(this.pos++);
var red = this.buffer.readUInt8(this.pos++);
var alpha = this.buffer.readUInt8(this.pos++);
var location = y * this.width * 4 + x * 4;
var location = line * this.width * 4 + x * 4;
this.data[location] = alpha;
this.data[location + 1] = red;
this.data[location + 2] = green;
Expand Down

0 comments on commit 832bcbc

Please sign in to comment.