Created
July 25, 2014 15:58
-
-
Save yurydelendik/24163fe1e3723e81f6bc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
https://github.com/mozilla/shumway/blob/95e002869175eb886b3c99038e867d8ab5a9912d/src/swf/bitmap.js