<commit_before>/**
 * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author <NAME> <<EMAIL>>
 */

import { Sphere3D } from '../../mol-math/geometry';
import { Vec3, Mat4 } from '../../mol-math/linear-algebra';
import { BoundaryHelper } from '../../mol-math/geometry/boundary-helper';
import { TextureFilter } from '../webgl/texture';

export function calculateTextureInfo (n: number, itemSize: number) {
    n = Math.max(n, 2); // observed issues with 1 pixel textures
    const sqN = Math.sqrt(n);
    let width = Math.ceil(sqN);
    width = width + (itemSize - (width % itemSize)) % itemSize;
    const height = width > 0 ? Math.ceil(n / width) : 0;
    return { width, height, length: width * height * itemSize };
}

export interface TextureImage<T extends Uint8Array | Float32Array | Int32Array> {
    readonly array: T
    readonly width: number
    readonly height: number
    readonly flipY?: boolean
    readonly filter?: TextureFilter
}

export interface TextureVolume<T extends Uint8Array | Float32Array> {
    readonly array: T
    readonly width: number
    readonly height: number
    readonly depth: number
}

export function createTextureImage<T extends Uint8Array | Float32Array>(n: number, itemSize: number, arrayCtor: new (length: number) => T, array?: T): TextureImage<T> {
    const { length, width, height } = calculateTextureInfo(n, itemSize);
    array = array && array.length >= length ? array : new arrayCtor(length);
    return { array, width, height };
}

export function printTextureImage(textureImage: TextureImage<any>, scale = 1) {
    const { array, width, height } = textureImage;
    const itemSize = array.length / (width * height);
    const data = new Uint8ClampedArray(width * height * 4);
    if (itemSize === 1) {
        for (let y = 0; y < height; ++y) {
            for (let x = 0; x < width; ++x) {
                data[(y * width + x) * 4 + 3] = array[y * width + x];
            }
        }
    } else if (itemSize === 4) {
        data.set(array);
    } else {
        console.warn(`itemSize '${itemSize}' not supported`);
    }
    return printImageData(new ImageData(data, width, height), scale);
}

export function printImageData(imageData: ImageData, scale = 1, pixelated = false) {
    const canvas = document.createElement('canvas');
    canvas.width = imageData.width;
    canvas.height = imageData.height;
    const ctx = canvas.getContext('2d');
    if (!ctx) throw new Error('Could not create canvas 2d context');
    ctx.putImageData(imageData, 0, 0);
    canvas.toBlob(imgBlob => {
        const objectURL = window.URL.createObjectURL(imgBlob);
        const img = document.createElement('img');
        img.src = objectURL;
        img.style.width = imageData.width * scale + 'px';
        img.style.height = imageData.height * scale + 'px';
        if (pixelated) {
            // not supported in Firefox and IE
            img.style.imageRendering = 'pixelated';
        }
        img.style.position = 'absolute';
        img.style.top = '0px';
        img.style.left = '0px';
        img.style.border = 'solid grey';
        img.style.pointerEvents = 'none';
        document.body.appendChild(img);
    }, 'image/png');
}

//

const v = Vec3();<commit_msg>tweak printImageData debug helper<commit_after>/**
 * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author <NAME> <<EMAIL>>
 */

import { Sphere3D } from '../../mol-math/geometry';
import { Vec3, Mat4 } from '../../mol-math/linear-algebra';
import { BoundaryHelper } from '../../mol-math/geometry/boundary-helper';
import { TextureFilter } from '../webgl/texture';

export function calculateTextureInfo (n: number, itemSize: number) {
    n = Math.max(n, 2); // observed issues with 1 pixel textures
    const sqN = Math.sqrt(n);
    let width = Math.ceil(sqN);
    width = width + (itemSize - (width % itemSize)) % itemSize;
    const height = width > 0 ? Math.ceil(n / width) : 0;
    return { width, height, length: width * height * itemSize };
}

export interface TextureImage<T extends Uint8Array | Float32Array | Int32Array> {
    readonly array: T
    readonly width: number
    readonly height: number
    readonly flipY?: boolean
    readonly filter?: TextureFilter
}

export interface TextureVolume<T extends Uint8Array | Float32Array> {
    readonly array: T
    readonly width: number
    readonly height: number
    readonly depth: number
}

export function createTextureImage<T extends Uint8Array | Float32Array>(n: number, itemSize: number, arrayCtor: new (length: number) => T, array?: T): TextureImage<T> {
    const { length, width, height } = calculateTextureInfo(n, itemSize);
    array = array && array.length >= length ? array : new arrayCtor(length);
    return { array, width, height };
}

export function printTextureImage(textureImage: TextureImage<any>, scale = 1) {
    const { array, width, height } = textureImage;
    const itemSize = array.length / (width * height);
    const data = new Uint8ClampedArray(width * height * 4);
    if (itemSize === 1) {
        for (let y = 0; y < height; ++y) {
            for (let x = 0; x < width; ++x) {
                data[(y * width + x) * 4 + 3] = array[y * width + x];
            }
        }
    } else if (itemSize === 4) {
        data.set(array);
    } else {
        console.warn(`itemSize '${itemSize}' not supported`);
    }
    return printImageData(new ImageData(data, width, height), scale);
}

export function printImageData(imageData: ImageData, scale = 1, pixelated = false) {
    const canvas = document.createElement('canvas');
    canvas.width = imageData.width;
    canvas.height = imageData.height;
    const ctx = canvas.getContext('2d');
    if (!ctx) throw new Error('Could not create canvas 2d context');
    ctx.putImageData(imageData, 0, 0);
    canvas.toBlob(imgBlob => {
        const objectURL = window.URL.createObjectURL(imgBlob);
        const img = document.createElement('img');
        img.src = objectURL;
        img.style.width = imageData.width * scale + 'px';
        img.style.height = imageData.height * scale + 'px';
        if (pixelated) {
            // not supported in Firefox and IE
            img.style.imageRendering = 'pixelated';
        }
        img.style.position = 'relative';
        img.style.top = '0px';
        img.style.left = '0px';
        img.style.border = 'solid grey';
        img.style.pointerEvents = 'none';
        document.body.appendChild(img);
    }, 'image/png');
}

//

const v = Vec3();
{'fraction_non_alphanumeric': 0.13515981735159818, 'fraction_numerical': 0.013089802130898021, 'mean_word_length': 2.902019002375297, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2860120', 'n_tokens_mistral': 2009, 'n_tokens_neox': 1948, 'n_words': 578}