Hi
Last active
August 29, 2015 14:27
-
-
Save Garciat/9c68351ac80ec4798558 to your computer and use it in GitHub Desktop.
This file contains 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
<script src="mem.js"></script> |
This file contains 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
// <definitions> | |
declare class Promise<T> { | |
constructor(f: (resolve: (value: T) => void, reject?: (error?: any) => void) => void); | |
then<R>(f: (value: T) => R | Promise<R>): Promise<R>; | |
} | |
declare module Promise { | |
function all<T>(promises: Promise<T>[]): Promise<T[]>; | |
function resolve<T>(value: T): Promise<T>; | |
} | |
interface Uint8ClampedArray { | |
buffer: ArrayBuffer; | |
set(array: Uint8ClampedArray, index: number): void; | |
} | |
declare var Uint8ClampedArray: { | |
new(size: number): Uint8ClampedArray; | |
new(buffer: ArrayBuffer): Uint8ClampedArray; | |
}; | |
interface Window { | |
ImageData: { | |
new(array: Uint8ClampedArray, width: number, height: number): ImageData; | |
}; | |
} | |
// </definitions> | |
// <functional> | |
function appendTo(parent: HTMLElement) { | |
return child => { | |
parent.appendChild(child); | |
}; | |
} | |
function snd<T1, T2>(pair: [T1, T2]) { | |
return pair[1]; | |
} | |
function applyPair<T1, T2, R>(f: (v1: T1, v2: T2) => R) { | |
return (pair: [T1, T2]) => { | |
let [v1, v2] = pair; | |
return f(v1, v2); | |
}; | |
} | |
// </functional> | |
function downloadArrayBuffer(url) { | |
return new Promise<ArrayBuffer>((resolve, reject) => { | |
let xhr = new XMLHttpRequest(); | |
xhr.open('GET', url, true); | |
xhr.responseType = 'arraybuffer'; | |
xhr.onload = () => { | |
resolve(xhr.response); | |
}; | |
xhr.onerror = () => { | |
reject(); | |
}; | |
xhr.send(); | |
}); | |
} | |
function downloadImage(url) { | |
return new Promise<HTMLImageElement>((resolve, reject) => { | |
let image = new Image(); | |
image.onload = () => { | |
resolve(image); | |
}; | |
image.onerror = () => { | |
reject(); | |
}; | |
image.src = url; | |
}); | |
} | |
const BYTES_PER_PIXEL = 4; | |
function fitBufferToSquare(buffer: ArrayBuffer): [number, ArrayBuffer] { | |
let S = Math.ceil(Math.sqrt(buffer.byteLength / BYTES_PER_PIXEL)); | |
let array = new Uint8Array(S * S * BYTES_PER_PIXEL); | |
array.set(new Uint8Array(buffer), 0); | |
return [S, array.buffer]; | |
} | |
function paintArrayBuffer(input: ArrayBuffer): HTMLCanvasElement { | |
let [S, buffer] = fitBufferToSquare(input); | |
let array = new Uint8ClampedArray(buffer); | |
let data = new window.ImageData(array, S, S); | |
let canvas = document.createElement('canvas'); | |
canvas.style.margin = '5px'; | |
canvas.width = canvas.height = S; | |
let ctx = canvas.getContext('2d'); | |
ctx.putImageData(data, 0, 0); | |
return canvas; | |
} | |
function decodeImage(image: HTMLImageElement): ArrayBuffer { | |
let canvas = document.createElement('canvas'); | |
canvas.width = image.width; | |
canvas.height = image.height; | |
let ctx = canvas.getContext('2d'); | |
ctx.drawImage(image, 0, 0); | |
let data = ctx.getImageData(0, 0, canvas.width, canvas.height); | |
let array = <Uint8ClampedArray> <any> data.data; | |
return array.buffer; | |
} | |
function compareBuffers(buf1: ArrayBuffer, buf2: ArrayBuffer) { | |
let arr1 = new Uint8Array(buf1); | |
let arr2 = new Uint8Array(buf2); | |
console.log(arr1); | |
console.log(arr2); | |
console.assert(arr1.byteLength === arr2.byteLength); | |
let diffs: number[] = []; | |
for (let i = 0; i < arr1.byteLength; ++i) { | |
if (arr1[i] !== arr2[i]) | |
diffs.push(i); | |
} | |
console.log(diffs); | |
console.log('compare finished (diffs = %d)', diffs.length); | |
Promise.resolve(buf1) | |
.then(paintArrayBuffer) | |
.then(appendTo(document.body)); | |
Promise.resolve(buf2) | |
.then(paintArrayBuffer) | |
.then(appendTo(document.body)); | |
} | |
function canvasToDataURL(type: string) { | |
return (canvas: HTMLCanvasElement) => { | |
return canvas.toDataURL(type); | |
}; | |
} | |
function main() { | |
Promise.all([ | |
downloadArrayBuffer('mem.bin') | |
.then(fitBufferToSquare) | |
.then(snd), | |
/* | |
downloadArrayBuffer('mem.bin') | |
.then(fitBufferToSquare) | |
.then(snd) | |
.then(paintArrayBuffer) | |
.then(canvasToDataURL('image/png')) | |
.then(downloadImage) | |
.then(decodeImage) | |
*/ | |
downloadImage('derp.png') | |
.then(decodeImage) | |
]).then(applyPair(compareBuffers)); | |
} | |
window.addEventListener('load', main); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment