gotty/js/spice-web-client/lib/images/bitmap.js

174 lines
4.9 KiB
JavaScript
Raw Permalink Normal View History

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;
}
});