Skip to content

Instantly share code, notes, and snippets.

@nowelium
Created March 27, 2012 22:42
Show Gist options
  • Save nowelium/2221106 to your computer and use it in GitHub Desktop.
Save nowelium/2221106 to your computer and use it in GitHub Desktop.
node.jsを使って【東方】Bad Apple!! PV【影絵】をコンソールに出力してみる
var fs = require('fs');
var util = require('util');
var async = require('async');
var Bitmap = require('./bitmap');
//
// ニコニコ動画の【東方】Bad Apple!! PV【影絵】 <http://www.nicovideo.jp/watch/sm8628149>
// を 30fps な bitmap に分割したので、
// それを読み込みつつ、コンソールに表示してみる。
//
// async <https://github.com/caolan/async>
// を使ってるので、 npm install async する
//
// youtubeにモッサリ動画を上げてみた。<http://youtu.be/IALA76KSc4I>
// 音付きにしてニコニコ動画に上げてみた。<http://www.nicovideo.jp/watch/sm17397285>
//
var imageSequenceDir = 'badapple_30fps_160_120';
fs.readdir(__dirname + '/' + imageSequenceDir, function(err, files){
if(err){
throw err;
}
var pathes = files.map(function(file){
return __dirname + '/' + imageSequenceDir + '/' + file;
}).filter(function(path){
if(/\.bmp$/.test(path)){
return true;
}
return false;
});
// コンソールに出すときに半角スペースと#の文字列に変換
Bitmap.prototype.mapRGBA = function(r, g, b){
if(255 == r && 255 == g && 255 == b){
return ' ';
}
return '##';
};
var render = async.queue(function(view, next){
util.print('\033[2J');
util.print(view);
util.print('\033[0;0H');
return next(null);
}, 1);
var queue = async.queue(function(path, next){
return fs.readFile(path, next);
}, 8);
var serial = [];
queue.push(pathes, function(err, buffer){
if(err){
throw err;
}
var bitmap = new Bitmap(buffer);
bitmap.init();
if(!bitmap.isBitmap()){
throw new Error('not bitmap');
}
serial.push(function(next){
var values = bitmap.getData();
var view = values.map(function(line){
return line.join('');
});
return render.push(view.join('\n'), function(){
return setTimeout(next, 22);
});
});
});
queue.drain = function(){
async.series(serial, function(err, results){
if(err){
console.error(err);
return process.exit(1);
}
console.log('\033[2J'); // clear screen
return process.exit(0);
});
};
});
// origin:: https://github.com/nowelium/node-bitmap
var Bitmap = module.exports = exports = function(buffer){
this.buffer = buffer;
this.initialized = false;
this.fileHeader = null;
this.infoHeader = null;
this.coreHeader = null;
this.colorPalette = null;
this.dataPos = -1;
};
Bitmap.prototype.CORE_TYPE_WINDOWS_V3 = 40;
Bitmap.prototype.CORE_TYPE_WINDOWS_V4 = 108;
Bitmap.prototype.CORE_TYPE_WINDOWS_V5 = 124;
Bitmap.prototype.CORE_TYPE_OS2_V1 = 12;
Bitmap.prototype.CORE_TYPE_OS2_V2 = 64;
Bitmap.prototype.BITMAPCOREHEADER = Bitmap.prototype.CORE_TYPE_OS2_V1;
Bitmap.prototype.BITMAPINFOHEADER = Bitmap.prototype.CORE_TYPE_WINDOWS_V3;
Bitmap.prototype.BITMAPINFOHEADER2 = Bitmap.prototype.CORE_TYPE_OS2_V2;
Bitmap.prototype.BITMAPV4HEADER = Bitmap.prototype.CORE_TYPE_WINDOWS_V4;
Bitmap.prototype.BITMAPV5HEADER = Bitmap.prototype.CORE_TYPE_WINDOWS_V5;
Bitmap.prototype.COMPRESSION_BI_RGB = 0;
Bitmap.prototype.COMPRESSION_BI_RLE8 = 1;
Bitmap.prototype.COMPRESSION_BI_RLE4 = 2;
Bitmap.prototype.COMPRESSION_BI_BITFIELDS = 3;
Bitmap.prototype.COMPRESSION_BI_JPEG = 4;
Bitmap.prototype.COMPRESSION_BI_PNG = 5;
Bitmap.prototype.BITCOUNT_2 = 1;
Bitmap.prototype.BITCOUNT_16 = 4;
Bitmap.prototype.BITCOUNT_256 = 8;
Bitmap.prototype.BITCOUNT_16bit = 16;
Bitmap.prototype.BITCOUNT_24bit = 24;
Bitmap.prototype.BITCOUNT_32bit = 32;
Bitmap.prototype.init = function(){
this.readFileHeader();
this.readInfoHeader();
this.readCoreHeader();
this.readColorPalette();
this.initDataPos();
this.initialized = true;
};
Bitmap.prototype.checkInit = function (){
if(!this.initialized){
throw new Error('not initialized');
}
/* nop */
};
Bitmap.prototype.isBitmap = function(){
this.checkInit();
if('BM' == this.fileHeader.bfType){
return true;
}
return false;
};
Bitmap.prototype.getData = function (){
this.checkInit();
if(this.COMPRESSION_BI_RGB !== this.coreHeader.__copmression__){
throw new Error('not supported compression: ' + this.coreHeader.__copmression__);
}
var bitCount = this.coreHeader.__bitCount__;
var width = this.getWidth();
var height = this.getHeight();
var line = (width * bitCount) / 8;
if(0 != (line % 4)){
line = ((line / 4) + 1) * 4;
}
var rgbaData = [];
var dataPos = this.dataPos;
for(var i = 0; i < height; ++i) {
var pos = dataPos + (line * (height - (i + 1)));
var buf = this.buffer.slice(pos, pos + line);
var color = this.mapColor(buf, bitCount);
rgbaData.push(color);
}
return rgbaData;
};
Bitmap.prototype.getWidth = function (){
this.checkInit();
return this.coreHeader.__width__;
};
Bitmap.prototype.getHeight = function (){
this.checkInit();
return this.coreHeader.__height__;
};
Bitmap.prototype.read = function(buf, offset, limit){
var read = [];
for(var i = offset, len = offset + limit; i < len; ++i){
read.push(buf.readInt8(i));
}
return new Buffer(read);
};
Bitmap.prototype.readFileHeader = function(){
var bfType = this.read(this.buffer, 0, 2);
var bfSize = this.read(this.buffer, 2, 4);
var bfReserved1 = this.read(this.buffer, 6, 2);
var bfReserved2 = this.read(this.buffer, 8, 2);
var bfOffBits = this.read(this.buffer, 10, 4);
this.fileHeader = {
bfType: bfType.toString('ascii'),
_bfType: bfType,
bfSize: bfSize.readUInt16LE(0),
_bfSize: bfSize,
bfReserved1: 0,
bfReserved2: 0,
bfOffBits: bfOffBits.readUInt16LE(0),
_bfOffBits: bfOffBits
};
};
Bitmap.prototype.readInfoHeader = function (){
this.infoHeader = this.read(this.buffer, 14, 4);
};
Bitmap.prototype.readCoreHeader = function (){
var coreType = this.infoHeader.readUInt16LE(0);
switch(coreType){
case this.BITMAPCOREHEADER:
return this.readCoreHeaderOS2_V1();
case this.BITMAPINFOHEADER2:
return this.readCoreHeaderOS2_V2();
case this.BITMAPV4HEADER:
return this.readCoreHeaderWINDOWS_V4();
case this.BITMAPV5HEADER:
return this.readCoreHeaderWINDOWS_V5();
case this.BITMAPINFOHEADER:
return this.readCoreHeaderWINDOWS_V3();
default:
throw new Error('unknown coreType: ' + coreType);
}
};
Bitmap.prototype.readCoreHeaderWINDOWS_V3 = function (){
var biWidth = this.read(this.buffer, 0x12, 4);
var biHeight = this.read(this.buffer, 0x16, 4);
var biPlanes = this.read(this.buffer, 0x1a, 2);
var biBitCount = this.read(this.buffer, 0x1c, 2);
var biCopmression = this.read(this.buffer, 0x1e, 4);
var biSizeImage = this.read(this.buffer, 0x22, 4);
var biXPixPerMeter = this.read(this.buffer, 0x26, 4);
var biYPixPerMeter = this.read(this.buffer, 0x2a, 4);
var biClrUsed = this.read(this.buffer, 0x2e, 4);
var biCirImportant = this.read(this.buffer, 0x32, 4);
this.coreHeader = {
__copmression__: biCopmression.readUInt16LE(0),
__bitCount__: biBitCount.readUInt8(0),
__width__: biWidth.readUInt16LE(0),
__height__: biHeight.readUInt16LE(0),
biWidth: biWidth.readUInt16LE(0),
_biWidth: biWidth,
biHeight: biHeight.readUInt16LE(0),
_biHeight: biHeight,
biPlanes: biPlanes.readUInt8(0),
_biPlanes: biPlanes,
biBitCount: biBitCount.readUInt8(0),
_biBitCount: biBitCount,
biCopmression: biCopmression.readUInt16LE(0),
_biCopmression: biCopmression,
biSizeImage: biSizeImage.readUInt16LE(0),
_biSizeImage: biSizeImage,
biXPixPerMeter: biXPixPerMeter.readUInt16LE(0),
_biXPixPerMeter: biXPixPerMeter,
biYPixPerMeter: biYPixPerMeter.readUInt16LE(0),
_biYPixPerMeter: biYPixPerMeter,
biClrUsed: biClrUsed.readUInt16LE(0),
_biClrUsed: biClrUsed,
biCirImportant: biCirImportant.readUInt16LE(0),
_biCirImportant: biCirImportant
};
};
Bitmap.prototype.readCoreHeaderWINDOWS_V4 = function (){
throw new Error('not yet impl');
var bV4Width = this.read(this.buffer, 0x12, 4);
var bV4Height = this.read(this.buffer, 0x16, 4);
var bV4Planes = this.read(this.buffer, 0x1a, 2);
var bV4BitCount = this.read(this.buffer, 0x1c, 2);
var bV4Compression = this.read(this.buffer, 0x1e, 4);
var bV4SizeImage = this.read(this.buffer, 0x22, 4);
var bV4XPelsPerMeter = this.read(this.buffer, 0x26, 4);
var bV4YPelsPerMeter = this.read(this.buffer, 0x2a, 4);
var bV4ClrUsed = this.read(this.buffer, 0x2e, 4);
var bV4ClrImportant = this.read(this.buffer, 0x32, 4);
var bV4RedMask = this.read(this.buffer, 0x36, 4);
var bV4GreenMask = this.read(this.buffer, 0x3a, 4);
var bV4BlueMask = this.read(this.buffer, 0x3e, 4);
var bV4AlphaMask = this.read(this.buffer, 0x42, 4);
var bV4CSType = this.read(this.buffer, 0x46, 4);
var bV4Endpoints = this.read(this.buffer, 0x6a, 36);
var bV4GammaRed = this.read(this.buffer, 0x6e, 4);
var bV4GammaGreen = this.read(this.buffer, 0x72, 4);
var bV4GammaBlue = this.read(this.buffer, 0x76, 4);
this.coreHeader = {
__compression__: bV4Compression.readUInt16LE(0),
__bitCount__: bV4BitCount.readUInt8(0),
__width__: bV4Width.readUInt16LE(0),
__height__: bV4Height.readUInt16LE(0),
bV4Width: bV4Width.readUInt16LE(0),
_bV4Width: bV4Width,
bV4Height: bV4Height.readUInt16LE(0),
_bV4Height: bV4Height,
bV4Planes: bV4Planes.readUInt8(0),
_bV4Planes: bV4Planes,
bV4BitCount: bV4BitCount.readUInt8(0),
_bV4BitCount: bV4BitCount,
bV4Compression: bV4Compression.readUInt16LE(0),
_bV4Compression: bV4Compression,
bV4SizeImage: bV4SizeImage.readUInt16LE(0),
_bV4SizeImage: bV4SizeImage,
bV4XPelsPerMeter: bV4XPelsPerMeter.readUInt16LE(0),
_bV4XPelsPerMeter: bV4XPelsPerMeter,
bV4YPelsPerMeter: bV4YPelsPerMeter.readUInt16LE(0),
_bV4YPelsPerMeter: bV4YPelsPerMeter,
bV4ClrUsed: bV4ClrUsed.readUInt16LE(0),
_bV4ClrUsed: bV4ClrUsed,
bV4ClrImportant: bV4ClrImportant.readUInt16LE(0),
_bV4ClrImportant: bV4ClrImportant,
bV4RedMask: bV4RedMask.readUInt16LE(0),
_bV4RedMask: bV4RedMask,
bV4GreenMask: bV4GreenMask.readUInt16LE(0),
_bV4GreenMask: bV4GreenMask,
bV4BlueMask: bV4BlueMask.readUInt16LE(0),
_bV4BlueMask: bV4BlueMask,
bV4AlphaMask: bV4AlphaMask.readUInt16LE(0),
_bV4AlphaMask: bV4AlphaMask,
bV4CSType: bV4CSType.readUInt16LE(0),
_bV4CSType: bV4CSType,
bV4Endpoints: null,
_bV4Endpoints: bV4Endpoints,
bV4GammaRed: bV4GammaRed.readUInt16LE(0),
_bV4GammaRed: bV4GammaRed,
bV4GammaGreen: bV4GammaGreen.readUInt16LE(0),
_bV4GammaGreen: bV4GammaGreen,
bV4GammaBlue: bV4GammaBlue.readUInt16LE(0),
_bV4GammaBlue: bV4GammaBlue
};
};
Bitmap.prototype.readCoreHeaderWINDOWS_V5 = function (){
throw new Error('not yet impl');
var bV5Width = this.read(this.buffer, 0x12, 4);
var bV5Height = this.read(this.buffer, 0x16, 4);
var bV5Planes = this.read(this.buffer, 0x1a, 2);
var bV5BitCount = this.read(this.buffer, 0x1c, 2);
var bV5Compression = this.read(this.buffer, 0x1e, 4);
var bV5SizeImage = this.read(this.buffer, 0x22, 4);
var bV5XPelsPerMeter = this.read(this.buffer, 0x26, 4);
var bV5YPelsPerMeter = this.read(this.buffer, 0x2a, 4);
var bV5ClrUsed = this.read(this.buffer, 0x2e, 4);
var bV5ClrImportant = this.read(this.buffer, 0x32, 4);
var bV5RedMask = this.read(this.buffer, 0x36, 4);
var bV5GreenMask = this.read(this.buffer, 0x3a, 4);
var bV5BlueMask = this.read(this.buffer, 0x3e, 4);
var bV5AlphaMask = this.read(this.buffer, 0x42, 4);
var bV5CSType = this.read(this.buffer, 0x46, 4);
var bV5Endpoints = this.read(this.buffer, 0x6a, 36);
var bV5GammaRed = this.read(this.buffer, 0x6e, 4);
var bV5GammaGreen = this.read(this.buffer, 0x72, 4);
var bV5GammaBlue = this.read(this.buffer, 0x76, 4);
var bV5Intent = this.read(this.buffer, 0x7a, 4);
var bV5ProfileData = this.read(this.buffer, 0x7e, 4);
var bV5ProfileSize = this.read(this.buffer, 0x82, 4);
var bV5Reserved = this.read(this.buffer, 0x86, 4);
this.coreHeader = {
__compression__: bV5Compression.readUInt16LE(0),
__bitCount__: bV5BitCount.readUInt8(0),
__width__: bV5Width.readUInt16LE(0),
__height__: bV5Height.readUInt16LE(0),
bV5Width: bV5Width.readUInt16LE(0),
_bV5Width: bV5Width,
bV5Height: bV5Height.readUInt16LE(0),
_bV5Height: bV5Height,
bV5Planes: bV5Planes.readUInt8(0),
_bV5Planes: bV5Planes,
bV5BitCount: bV5BitCount.readUInt8(0),
_bV5BitCount: bV5BitCount,
bV5Compression: bV5Compression.readUInt16LE(0),
_bV5Compression: bV5Compression,
bV5SizeImage: bV5SizeImage.readUInt16LE(0),
_bV5SizeImage: bV5SizeImage,
bV5XPelsPerMeter: bV5XPelsPerMeter.readUInt16LE(0),
_bV5XPelsPerMeter: bV5XPelsPerMeter,
bV5YPelsPerMeter: bV5YPelsPerMeter.readUInt16LE(0),
_bV5YPelsPerMeter: bV5YPelsPerMeter,
bV5ClrUsed: bV5ClrUsed.readUInt16LE(0),
_bV5ClrUsed: bV5ClrUsed,
bV5ClrImportant: bV5ClrImportant.readUInt16LE(0),
_bV5ClrImportant: bV5ClrImportant,
bV5RedMask: bV5RedMask.readUInt16LE(0),
_bV5RedMask: bV5RedMask,
bV5GreenMask: bV5GreenMask.readUInt16LE(0),
_bV5GreenMask: bV5GreenMask,
bV5BlueMask: bV5BlueMask.readUInt16LE(0),
_bV5BlueMask: bV5BlueMask,
bV5AlphaMask: bV5AlphaMask.readUInt16LE(0),
_bV5AlphaMask: bV5AlphaMask,
bV5CSType: bV5CSType.readUInt16LE(0),
_bV5CSType: bV5CSType,
bV5Endpoints: null,
_bV5Endpoints: bV5Endpoints,
bV5GammaRed: bV5GammaRed.readUInt16LE(0),
_bV5GammaRed: bV5GammaRed,
bV5GammaGreen: bV5GammaGreen.readUInt16LE(0),
_bV5GammaGreen: bV5GammaGreen,
bV5GammaBlue: bV5GammaBlue.readUInt16LE(0),
_bV5GammaBlue: bV5GammaBlue,
bV5Intent: bV5Intent.readUInt16LE(0),
_bV5Intent: bV5Intent,
bV5ProfileData: bV5ProfileData.readUInt16LE(0),
_bV5ProfileData: bV5ProfileData,
bV5ProfileSize: bV5ProfileSize.readUInt16LE(0),
_bV5ProfileSize: bV5ProfileSize,
bV5Reserved: 0,
_bV5Reserved: bV5Reserved
};
};
Bitmap.prototype.readCoreHeaderOS2_V1 = function (){
throw new Error('not yet impl');
var bcWidth = this.read(this.buffer, 0x12, 2);
var bcHeight = this.read(this.buffer, 0x14, 2);
var bcPlanes = this.read(this.buffer, 0x16, 2);
var bcBitCount = this.read(this.buffer, 0x18, 2);
this.coreHeader = {
__compression__: 0,
__bitCount__: bcBitCount.readUInt8(0),
__width__: bcWidth.readUInt8(0),
__height__: bcHeight.readUInt8(0),
bcWidth: bcWidth.readUInt8(0),
_bcWidth: bcWidth,
bcHeight: bcHeight.readUInt8(0),
_bcHeight: bcHeight,
bcPlanes: bcPlanes.readUInt8(0),
_bcPlanes: bcPlanes,
bcBitCount: bcBitCount.readUInt8(0),
_bcBitCount: bcBitCount
};
};
Bitmap.prototype.readCoreHeaderOS2_V2 = function (){
throw new Error('not yet impl');
var cx = this.read(this.buffer, 0x12, 4);
var cy = this.read(this.buffer, 0x16, 4);
var cPlanes = this.read(this.buffer, 0x1a, 2);
var cBitCount = this.read(this.buffer, 0x1c, 2);
var ulCompression = this.read(this.buffer, 0x1e, 4);
var cbImage = this.read(this.buffer, 0x22, 4);
var cxResolution = this.read(this.buffer, 0x26, 4);
var cyResolution = this.read(this.buffer, 0x2a, 4);
var cclrUsed = this.read(this.buffer, 0x2e, 4);
var cclrImportant = this.read(this.buffer, 0x32, 4);
var usUnits = this.read(this.buffer, 0x36, 2);
var usReserved = this.read(this.buffer, 0x38, 2);
var usRecording = this.read(this.buffer, 0x3a, 2);
var usRendering = this.read(this.buffer, 0x3c, 2);
var cSize1 = this.read(this.buffer, 0x3e, 4);
var cSize2 = this.read(this.buffer, 0x42, 4);
var ulColorEncoding = this.read(this.buffer, 0x46, 4);
var ulIdentifier = this.read(this.buffer, 0x4a, 4);
this.coreHeader = {
__compression__: ulCompression.readUInt16LE(0),
__bitCount__: cBitCount.readUInt8(0),
__width__: cx.readUInt16LE(0),
__height__: cy.readUInt16LE(0),
cx: cx.readUInt16LE(0),
_cx: cx,
cy: cy.readUInt16LE(0),
_cy: cy,
cPlanes: cPlanes.readUInt8(0),
_cPlanes: cPlanes,
cBitCount: cBitCount.readUInt8(0),
_cBitCount: cBitCount,
ulCompression: ulCompression.readUInt16LE(0),
_ulCompression: ulCompression,
cbImage: cbImage.readUInt16LE(0),
_cbImage: cbImage,
cxResolution: cxResolution.readUInt16LE(0),
_cxResolution: cxResolution,
cyResolution: cyResolution.readUInt16LE(0),
_cyResolution: cyResolution,
cclrUsed: cclrUsed.readUInt16LE(0),
_cclrUsed: cclrUsed,
cclrImportant: cclrImportant.readUInt16LE(0),
_cclrImportant: cclrImportant,
usUnits: usUnits.readUInt8(0),
_usUnits: usUnits,
usReserved: usReserved.readUInt8(0),
_usReserved: usReserved,
usRecording: usRecording.readUInt8(0),
_usRecording: usRecording,
usRendering: usRendering.readUInt8(0),
_usRendering: usRendering,
cSize1: cSize1.readUInt16LE(0),
_cSize1: cSize1,
cSize2: cSize2.readUInt16LE(0),
_cSize1: cSize1,
ulColorEncoding: ulColorEncoding.readUInt16LE(0),
_ulColorEncoding: ulColorEncoding,
ulIdentifier: ulIdentifier.readUInt16LE(0),
_ulIdentifier: ulIdentifier
};
};
Bitmap.prototype.readColorPalette = function (){
var bitCount = this.coreHeader.__bitCount__;
if(this.BITCOUNT_16bit == bitCount){
return /* nop */;
}
if(this.BITCOUNT_24bit == bitCount){
return /* nop */;
}
if(this.BITCOUNT_32bit == bitCount){
return /* nop */;
}
var coreType = this.infoHeader.readUInt16LE(0);
switch(coreType){
case this.BITMAPCOREHEADER:
return this.readColorPalette_RGBTRIPLE(bitCount, 0x1a);
case this.BITMAPINFOHEADER2:
return this.readColorPalette_RGBTRIPLE(bitCount, 0x4e);
case this.BITMAPV4HEADER:
return this.readColorPalette_RGBQUAD(bitCount, 0x7a);
case this.BITMAPV5HEADER:
return this.readColorPalette_RGBQUAD(bitCount, 0x8a);
case this.BITMAPINFOHEADER:
return this.readColorPalette_RGBQUAD(bitCount, 0x36);
default:
throw new Error('unknown colorPalette: ' + coreType + ',' + bitCount);
}
};
Bitmap.prototype.readColorPalette_RGBTRIPLE = function (bitCount, startPos){
throw new Error('not yet impl');
};
Bitmap.prototype.readColorPalette_RGBQUAD = function (bitCount, startPos){
if(this.BITCOUNT_2 == bitCount){
return this.readRGBQUAD(1 << this.BITCOUNT_2, startPos);
}
if(this.BITCOUNT_16 == bitCount){
return this.readRGBQUAD(1 << this.BITCOUNT_16, startPos);
}
if(this.BITCOUNT_256 == bitCount){
return this.readRGBQUAD(1 << this.BITCOUNT_256, startPos);
}
throw new Error('unknown bitCount: ' + bitCount);
};
Bitmap.prototype.readRGBQUAD = function(count, startPos){
var palette = [];
for(var i = startPos, len = startPos + (4 * count); i < len; i += 4){
palette.push({
rgbBlue: this.read(this.buffer, i, 1).readUInt8(0),
rgbGreen: this.read(this.buffer, i + 1, 1).readUInt8(0),
rgbRed: this.read(this.buffer, i + 2, 1).readUInt8(0),
rgbReserved: this.read(this.buffer, i + 3, 1).readUInt8(0)
});
}
this.colorPalette = palette;
};
Bitmap.prototype.initDataPos = function(){
var bitCount = this.coreHeader.__bitCount__;
var hasPalette = true;
if(this.BITCOUNT_16bit == bitCount){
hasPalette = true;
}
if(this.BITCOUNT_24bit == bitCount){
hasPalette = true;
}
if(this.BITCOUNT_32bit == bitCount){
hasPalette = true;
}
var coreType = this.infoHeader.readUInt16LE(0);
switch(coreType){
case this.BITMAPCOREHEADER:
this.dataPos = 0x1a;
if(hasPalette){
this.dataPos = this.dataPos + (3 * (1 << bitCount));
}
break;
case this.BITMAPINFOHEADER2:
this.dataPos = 0x4e;
if(hasPalette){
this.dataPos = this.dataPos + (3 * (1 << bitCount));
}
break;
case this.BITMAPV4HEADER:
this.dataPos = 0x7a;
if(hasPalette){
this.dataPos = this.dataPos + (4 * (1 << bitCount));
}
break;
case this.BITMAPV5HEADER:
this.dataPos = 0x8a;
if(hasPalette){
this.dataPos = this.dataPos + (4 * (1 << bitCount));
}
case this.BITMAPINFOHEADER:
this.dataPos = 0x36;
if(hasPalette){
this.dataPos = this.dataPos + (4 * (1 << bitCount));
}
break;
default:
throw new Error('unknown colorPalette: ' + coreType + ',' + bitCount);
}
};
Bitmap.prototype.mapRGBA = function(r, g, b, a){
var hex = [];
var padHex = function(value){
var h = value.toString(16);
if(value < 0x0f){
return '0' + h;
}
return h;
};
hex.push(padHex(r));
hex.push(padHex(g));
hex.push(padHex(b));
return '#' + hex.join('');
};
Bitmap.prototype.mapColor = function(bmpBuf, bitCount){
var b, g, r, a;
var length = bmpBuf.length;
var colorData = [];
if(this.BITCOUNT_2 == bitCount){
for(var i = 0; i < length; ++i){
var paletteValue = bmpBuf[i];
var bin = paletteValue.toString(2);
bin = new Array(8 - bin.length).join('0') + bin;
for(var j = 0; j < bin.length; ++j){
var paletteIndex = parseInt(bin.substring(j, j + 1), 10);
var palette = this.colorPalette[paletteIndex];
colorData.push(this.mapRGBA(palette.rgbRed, palette.rgbGreen, palette.rgbBlue, -1));
}
}
return colorData;
}
if(this.BITCOUNT_16 == bitCount){
for(var i = 0; i < length; i += 2){
var paletteHigh = bmpBuf.readUInt8(i);
var paletteLow = bmpBuf.readUInt8(i + 1);
var indexes = [paletteHigh, paletteLow];
indexes.forEach(function(paletteIndex){
var palette = this.colorPalette[paletteIndex];
colorData.push(this.mapRGBA(palette.rgbRed, palette.rgbGreen, palette.rgbBlue, -1));
});
}
return colorData;
}
if(this.BITCOUNT_256 == bitCount){
for(var i = 0; i < length; ++i){
var paletteIndex = bmpBuf.readUInt16LE(i);
var palette = this.colorPalette[paletteIndex];
colorData.push(this.mapRGBA(palette.rgbRed, palette.rgbGreen, palette.rgbBlue, -1));
}
return colorData;
}
if(this.BITCOUNT_16bit == bitCount){
for(var i = 0; i < length; i += 3){
b = bmpBuf[i];
g = bmpBuf[i + 1];
r = bmpBuf[i + 2];
colorData.push(this.mapRGBA(r, g, b, -1));
}
return colorData;
}
if(this.BITCOUNT_24bit == bitCount){
for(var i = 0; i < length; i += 3){
b = bmpBuf[i];
g = bmpBuf[i + 1];
r = bmpBuf[i + 2];
colorData.push(this.mapRGBA(r, g, b, -1));
}
return colorData;
}
if(this.BITCOUNT_32bit == bitCount){
for(var i = 0; i < length; i += 4){
b = bmpBuf[i];
g = bmpBuf[i + 1];
r = bmpBuf[i + 2];
a = bmpBuf[i + 3];
colorData.push(this.mapRGBA(r, g, b, a));
}
return colorData;
}
throw new Error('unknown bitCount: ' + bitCount);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment