//
declare class Promise {
constructor(f: (resolve: (value: T) => void, reject?: (error?: any) => void) => void);
then(f: (value: T) => R | Promise): Promise;
}
declare module Promise {
function all(promises: Promise[]): Promise;
function resolve(value: T): Promise;
}
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;
};
}
//
//
function appendTo(parent: HTMLElement) {
return child => {
parent.appendChild(child);
};
}
function snd(pair: [T1, T2]) {
return pair[1];
}
function applyPair(f: (v1: T1, v2: T2) => R) {
return (pair: [T1, T2]) => {
let [v1, v2] = pair;
return f(v1, v2);
};
}
//
function downloadArrayBuffer(url) {
return new Promise((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((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 = 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);