"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.methods = void 0;
exports.distance = distance;
exports.compareHashes = compareHashes;
const any_base_1 = __importDefault(require("any-base"));
const phash_js_1 = __importDefault(require("./phash.js"));
// an array storing the maximum string length of hashes at various bases
// 0 and 1 do not exist as possible hash lengths
// prettier-ignore
const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
// an array storing the maximum string length of hashes at various bases
// 0 and 1 do not exist as possible hash lengths
const maxHashLength = [NaN, NaN];
for (let i = 2; i < 65; i++) {
    const maxHash = (0, any_base_1.default)(any_base_1.default.BIN, alphabet.slice(0, i))(new Array(64 + 1).join("1"));
    maxHashLength.push(maxHash.length);
}
exports.methods = {
    /**
     * Calculates the perceptual hash
     * @returns the perceptual hash
     * @example
     * ```ts
     * import { Jimp } from "jimp";
     *
     * const image = await Jimp.read("test/image.png");
     *
     * image.hash();
     * ```
     */
    pHash(image) {
        const pHash = new phash_js_1.default();
        return pHash.getHash(image);
    },
    /**
     * Generates a perceptual hash of the image <https://en.wikipedia.org/wiki/Perceptual_hashing>. And pads the string. Can configure base.
     * @param base A number between 2 and 64 representing the base for the hash (e.g. 2 is binary, 10 is decimal, 16 is hex, 64 is base 64). Defaults to 64.
     * @example
     * ```ts
     * import { Jimp } from "jimp";
     *
     * const image = await Jimp.read("test/image.png");
     *
     * image.hash(2); // binary
     * image.hash(64); // base 64
     * ```
     */
    hash(image, base = 64) {
        if (base < 2 || base > 64) {
            throw new Error("base must be a number between 2 and 64");
        }
        const subAlphabet = alphabet.slice(0, base);
        const pHash = this.pHash(image);
        const maxLength = maxHashLength[base];
        return (0, any_base_1.default)(any_base_1.default.BIN, subAlphabet)(pHash).padStart(maxLength, "0");
    },
    /**
     * Calculates the hamming distance of the current image and a hash based on their perceptual hash
     * @param compareHash hash to compare to
     * @returns  a number ranging from 0 to 1, 0 means they are believed to be identical
     * @example
     * ```ts
     * import { Jimp } from "jimp";
     *
     * const image = await Jimp.read("test/image.png");
     *
     * image.distanceFromHash(image.pHash());
     * ```
     */
    distanceFromHash(image, compareHash) {
        const pHash = new phash_js_1.default();
        const currentHash = pHash.getHash(image);
        return pHash.distance(currentHash, compareHash);
    },
};
/**
 * Calculates the hamming distance of two images based on their perceptual hash
 * @param img1 A Jimp image to compare
 * @param img2 A Jimp image to compare
 * @returns A number ranging from 0 to 1, 0 means they are believed to be identical
 * @example
 * ```ts
 * import { Jimp, distance } from "jimp";
 *
 * const image1 = await Jimp.read("test/image.png");
 * const image2 = await Jimp.read("test/image.png");
 *
 * distance(image1, image2); // 0.5
 * ```
 */
function distance(img1, img2) {
    const phash = new phash_js_1.default();
    const hash1 = phash.getHash(img1);
    const hash2 = phash.getHash(img2);
    return phash.distance(hash1, hash2);
}
/**
 * Calculates the hamming distance of two images based on their perceptual hash
 * @param hash1 A pHash
 * @param hash2 A pHash
 * @returns A number ranging from 0 to 1, 0 means they are believed to be identical
 * @example
 * ```ts
 * import { Jimp, compareHashes } from "jimp";
 *
 * const image1 = await Jimp.read("test/image.png");
 * const image2 = await Jimp.read("test/image.png");
 *
 * compareHashes(image1.pHash(), image2.pHash()); // 0.5
 * ```
 */
function compareHashes(hash1, hash2) {
    const phash = new phash_js_1.default();
    return phash.distance(hash1, hash2);
}