Skip to content

Instantly share code, notes, and snippets.

@yurydelendik
Created July 25, 2014 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yurydelendik/24163fe1e3723e81f6bc to your computer and use it in GitHub Desktop.
Save yurydelendik/24163fe1e3723e81f6bc to your computer and use it in GitHub Desktop.
var dumpImage = (function() {
var crcTable = [];
for (var i = 0; i < 256; i++) {
var c = i;
for (var h = 0; h < 8; h++) {
if (c & 1)
c = 0xedB88320 ^ ((c >> 1) & 0x7fffffff);
else
c = (c >> 1) & 0x7fffffff;
}
crcTable[i] = c;
}
function crc32(data, start, end){
var crc = -1;
for (var i = start; i < end; i++) {
var a = (crc ^ data[i]) & 0xff;
var b = crcTable[a];
crc = (crc >>> 8) ^ b;
}
return crc ^ -1;
}
function createPngChunk(type, data) {
var chunk = new Uint8Array(12 + data.length);
var p = 0;
var len = data.length;
chunk[p] = len >> 24 & 0xff;
chunk[p + 1] = len >> 16 & 0xff;
chunk[p + 2] = len >> 8 & 0xff;
chunk[p + 3] = len & 0xff;
chunk[p + 4] = type.charCodeAt(0) & 0xff;
chunk[p + 5] = type.charCodeAt(1) & 0xff;
chunk[p + 6] = type.charCodeAt(2) & 0xff;
chunk[p + 7] = type.charCodeAt(3) & 0xff;
if (data instanceof Uint8Array)
chunk.set(data, 8);
p = 8 + len;
var crc = crc32(chunk, 4, p);
chunk[p] = crc >> 24 & 0xff;
chunk[p + 1] = crc >> 16 & 0xff;
chunk[p + 2] = crc >> 8 & 0xff;
chunk[p + 3] = crc & 0xff;
return chunk;
}
function adler32(data, start, end) {
var a = 1;
var b = 0;
for (var i = start; i < end; ++i) {
a = (a + (data[i] & 0xff)) % 65521;
b = (b + a) % 65521;
}
return (b << 16) | a;
}
function encode(imgData, kind) {
var width = imgData.width;
var height = imgData.height;
var bitDepth;
var colorType;
var bytes = imgData.data;
var lineSize;
switch (kind) {
case ImageKind.GRAYSCALE_1BPP:
colorType = 0;
bitDepth = 1;
lineSize = (width + 7) >> 3;
break;
case ImageKind.RGB_24BPP:
colorType = 2;
bitDepth = 8;
lineSize = width * 3;
break;
case ImageKind.RGBA_32BPP:
colorType = 6;
bitDepth = 8;
lineSize = width * 4;
break;
default:
throw new Error('invalid format');
}
var literals = new Uint8Array((1 + lineSize) * height);
var offsetLiterals = 0, offsetBytes = 0;
for (var y = 0; y < height; ++y) {
literals[offsetLiterals++] = 0;
literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), offsetLiterals);
offsetBytes += lineSize;
offsetLiterals += lineSize;
}
var ihdr = new Uint8Array([
width >> 24 & 0xff,
width >> 16 & 0xff,
width >> 8 & 0xff,
width & 0xff,
height >> 24 & 0xff,
height >> 16 & 0xff,
height >> 8 & 0xff,
height & 0xff,
bitDepth, // bit depth
colorType, // color type
0x00, // compression method
0x00, // filter method
0x00 // interlace method
]);
var len = literals.length;
var maxBlockLength = 0xFFFF;
var idat = new Uint8Array(2 + len + Math.ceil(len / maxBlockLength) * 5 + 4);
var pi = 0;
idat[pi++] = 0x78; // compression method and flags
idat[pi++] = 0x9c; // flags
var pos = 0;
while (len > maxBlockLength) {
idat[pi++] = 0x00;
idat[pi++] = 0xff;
idat[pi++] = 0xff;
idat[pi++] = 0x00;
idat[pi++] = 0x00;
idat.set(literals.subarray(pos, pos + maxBlockLength), pi);
pi += maxBlockLength;
pos += maxBlockLength;
len -= maxBlockLength;
}
idat[pi++] = 0x01;
idat[pi++] = len & 0xff;
idat[pi++] = len >> 8 & 0xff;
idat[pi++] = (~len & 0xffff) & 0xff;
idat[pi++] = (~len & 0xffff) >> 8 & 0xff;
idat.set(literals.subarray(pos), pi);
pi += literals.length - pos;
var adler = adler32(literals, 0, literals.length); // checksum
idat[pi++] = adler >> 24 & 0xff;
idat[pi++] = adler >> 16 & 0xff;
idat[pi++] = adler >> 8 & 0xff;
idat[pi++] = adler & 0xff;
var chunks = [
new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
createPngChunk('IHDR', ihdr),
createPngChunk('IDAT', idat),
createPngChunk('IEND', '')
];
var blob = new Blob(chunks, { type: 'image/png' });
return URL.createObjectURL(blob);
}
var d = null;
return function dumpImage(imgData) {
if (d === null) {
var w = window.open('about:blank', '_blank');
d = w.document.open('text/html');
}
var kind = imgData.kind === undefined ? ImageKind.GRAYSCALE_1BPP : imgData.kind;
var url = encode(imgData, kind);
d.writeln(imgData.width + 'x' + imgData.height + ' ' + kind + '<br>');
d.writeln('<img src=' + url + '><br>');
d.writeln('<hr>');
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment