mirror of
https://github.com/sorenisanerd/gotty.git
synced 2024-11-26 21:44:25 +00:00
174 lines
4.9 KiB
JavaScript
174 lines
4.9 KiB
JavaScript
|
wdi.BMP2 = $.spcExtend(wdi.SpiceObject, {
|
||
|
objectSize: 0,
|
||
|
mapper: [0, 1, 1, 4, 4, 8, 16, 24, 32, 32],
|
||
|
|
||
|
init: function(imageData) {
|
||
|
var type = this.bytesToInt8(imageData);
|
||
|
var flags = this.bytesToInt8(imageData); // bit 1 => normal, bit 2 => palette cache (...)
|
||
|
var width = this.bytesToInt32(imageData); // width in pixels
|
||
|
var height = this.bytesToInt32(imageData); // height in pixels
|
||
|
var stride = this.bytesToInt32(imageData); // width in bytes including padding
|
||
|
var len;
|
||
|
var bpp = this.mapper[type];
|
||
|
var i;
|
||
|
|
||
|
|
||
|
var paletteSize = 0, unique, paletteData, numEnts = 0;
|
||
|
if (bpp <= 8 && bpp > 0) {
|
||
|
var palette = [];
|
||
|
if (flags & 1) {
|
||
|
var paletteOffset = this.bytesToInt32(imageData); // From the begininig of the spice packet?
|
||
|
len = imageData.length;
|
||
|
paletteSize = 4*Math.pow(2,bpp);
|
||
|
var paletteDataSize = paletteSize + 8 + 2; //palette + unique(64b) + numEnts (16b)
|
||
|
len -= paletteDataSize;
|
||
|
paletteData = imageData.splice(len, paletteDataSize);
|
||
|
unique = this.bytesToInt64(paletteData);
|
||
|
numEnts = this.bytesToInt16(paletteData);
|
||
|
var queue;
|
||
|
|
||
|
for (i = 0; i < numEnts*4; i+=4) {
|
||
|
queue = new wdi.Queue();
|
||
|
queue.setData(paletteData.slice(i, i+4));
|
||
|
palette.push(new wdi.SpiceColor().demarshall(queue));
|
||
|
}
|
||
|
wdi.ImageCache.addPalette(unique, palette);
|
||
|
} else {
|
||
|
//get palette from cache
|
||
|
unique = this.bytesToInt64(imageData);
|
||
|
len = imageData.length;
|
||
|
palette = wdi.ImageCache.getPalette(unique);
|
||
|
var spiceColors;
|
||
|
paletteData = [];
|
||
|
numEnts = palette.length;
|
||
|
for (i =0; i < numEnts; i++ ) {
|
||
|
spiceColors = palette[i].marshall();
|
||
|
spiceColors.push(0);
|
||
|
paletteData = paletteData.concat(spiceColors);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
// imageData = paletteData.concat(imageData);
|
||
|
|
||
|
} else {
|
||
|
// Removing 4 bytes from the image data to fix index out of range error.
|
||
|
var unknown = this.bytesToInt32(imageData);
|
||
|
}
|
||
|
|
||
|
this.setContent({
|
||
|
imageSize: len,
|
||
|
width: width,
|
||
|
height: height,
|
||
|
bpp: bpp,
|
||
|
imageData: imageData,
|
||
|
paletteSize: numEnts * 4,
|
||
|
palette: palette,
|
||
|
stride: stride,
|
||
|
type: type
|
||
|
});
|
||
|
},
|
||
|
|
||
|
setContent: function(c) {
|
||
|
this.imageSize = c.imageSize;
|
||
|
this.width = c.width;
|
||
|
this.height = c.height;
|
||
|
this.bpp = c.bpp;
|
||
|
this.imageData = c.imageData;
|
||
|
this.palette = c.palette;
|
||
|
this.offset = c.paletteSize + 0x36; //0x36 === Current harcoded header size (BMP + DIB)
|
||
|
this.size = this.offset + this.imageSize;
|
||
|
this.stride = c.stride;
|
||
|
this.type = c.type;
|
||
|
},
|
||
|
|
||
|
marshall: function(context) {
|
||
|
var type = this.type;
|
||
|
var palette = this.palette;
|
||
|
var width = this.width;
|
||
|
var height = this.height;
|
||
|
var stride = this.stride;
|
||
|
var data = this.imageData;
|
||
|
var size = data.length;
|
||
|
|
||
|
var pixelsStride = stride * 8/this.bpp;
|
||
|
var bytesStride = pixelsStride * 4;
|
||
|
var buf = new ArrayBuffer(bytesStride * height);
|
||
|
var buf8 = new Uint8ClampedArray(buf);
|
||
|
var buf32 = new Uint32Array(buf);
|
||
|
var topdown = false;
|
||
|
|
||
|
var oct, i, pos, buffPos, spiceColor;
|
||
|
var b;
|
||
|
if (palette) {
|
||
|
buffPos = 0
|
||
|
if (type === wdi.SpiceBitmapFmt.SPICE_BITMAP_FMT_1BIT_BE) {
|
||
|
spiceColor = palette[1];
|
||
|
var foreColor = spiceColor.r << 24 | spiceColor.g << 16 | spiceColor.b << 8 | 255;
|
||
|
|
||
|
spiceColor = palette[0];
|
||
|
var backColor = spiceColor.r << 24 | spiceColor.g << 16 | spiceColor.b << 8 | 255;
|
||
|
|
||
|
var PLT1_MASK = [1, 2, 4, 8, 16, 32, 64, 128];
|
||
|
|
||
|
for (pos = 0; pos < size; pos++) {
|
||
|
oct = data[pos];
|
||
|
|
||
|
for (i = 7; i >= 0; i--) {
|
||
|
if (oct & PLT1_MASK[i]) {
|
||
|
buf32[buffPos++] = foreColor;
|
||
|
} else {
|
||
|
buf32[buffPos++] = backColor;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else if (type === wdi.SpiceBitmapFmt.SPICE_BITMAP_FMT_4BIT_BE) {
|
||
|
for (pos = 0; pos < size; pos++) {
|
||
|
oct = data[pos];
|
||
|
spiceColor = palette[oct >>> 4];
|
||
|
buf32[buffPos++] = spiceColor.r << 24 | spiceColor.g << 16 | spiceColor.b << 8 | 255;
|
||
|
spiceColor = palette[oct & 0x0f];
|
||
|
buf32[buffPos++] = spiceColor.r << 24 | spiceColor.g << 16 | spiceColor.b << 8 | 255;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
if (type === wdi.SpiceBitmapFmt.SPICE_BITMAP_FMT_32BIT) {
|
||
|
for (pos = 0; pos < size; pos += 4) {
|
||
|
b = data[pos];
|
||
|
data[pos] = data[pos + 2];
|
||
|
data[pos + 2] = b;
|
||
|
data[pos + 3] = 255;
|
||
|
}
|
||
|
|
||
|
} else if (type === wdi.SpiceBitmapFmt.SPICE_BITMAP_FMT_RGBA) {
|
||
|
topdown = true;
|
||
|
for (pos = 0; pos < size; pos+=4) {
|
||
|
b = data[pos];
|
||
|
data[pos] = data[pos+2];
|
||
|
data[pos+2] = b;
|
||
|
}
|
||
|
} else if (type === wdi.SpiceBitmapFmt.SPICE_BITMAP_FMT_24BIT) {
|
||
|
for (pos = 0; pos < size; pos+=3) {
|
||
|
b = data[pos];
|
||
|
data[pos] = data[pos+2];
|
||
|
data[pos+2] = b;
|
||
|
}
|
||
|
}
|
||
|
buf8 = new Uint8ClampedArray(data);
|
||
|
}
|
||
|
|
||
|
var ret = new ImageData(buf8, pixelsStride, height);
|
||
|
|
||
|
var tmpCanvas = wdi.graphics.getNewTmpCanvas(width, height);
|
||
|
tmpCanvas.getContext('2d').putImageData(ret, 0, 0, 0, 0, width, height);
|
||
|
ret = tmpCanvas;
|
||
|
|
||
|
if(!topdown) {
|
||
|
ret = wdi.RasterOperation.flip(ret);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
|
||
|
}
|
||
|
});
|