"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Rendering
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImageSource = exports.ImageSourceFormat = exports.ImageBuffer = exports.ImageBufferFormat = void 0;
exports.isPowerOfTwo = isPowerOfTwo;
exports.nextHighestPowerOfTwo = nextHighestPowerOfTwo;
exports.isValidImageSourceFormat = isValidImageSourceFormat;
exports.isBinaryImageSource = isBinaryImageSource;
/** Format of an [[ImageBuffer]].
 * The format determines how many bytes are allocated for each pixel in the buffer and the semantics of each byte.
 * @see [[ImageBuffer.getNumBytesPerPixel]]
 * @public
 * @extensions
 */
var ImageBufferFormat;
(function (ImageBufferFormat) {
    /** RGBA format - 4 bytes per pixel. */
    ImageBufferFormat[ImageBufferFormat["Rgba"] = 0] = "Rgba";
    /** RGB format - 3 bytes per pixel. */
    ImageBufferFormat[ImageBufferFormat["Rgb"] = 2] = "Rgb";
    /** 1 byte per pixel. */
    ImageBufferFormat[ImageBufferFormat["Alpha"] = 5] = "Alpha";
})(ImageBufferFormat || (exports.ImageBufferFormat = ImageBufferFormat = {}));
/** Uncompressed rectangular bitmap image data.
 * @public
 */
class ImageBuffer {
    /** Image data in which each pixel occupies 1 or more bytes depending of the [[ImageBufferFormat]]. */
    data;
    /** Format of the bytes in the image. */
    format;
    /** Width of image in pixels */
    width;
    /** Return the number of bytes allocated for each pixel. */
    get numBytesPerPixel() { return ImageBuffer.getNumBytesPerPixel(this.format); }
    /** Determine the number of bytes allocated to a single pixel for the specified format. */
    static getNumBytesPerPixel(format) {
        switch (format) {
            case ImageBufferFormat.Alpha: return 1;
            case ImageBufferFormat.Rgb: return 3;
            default: return 4;
        }
    }
    /** Get the height of this image in pixels. */
    get height() { return ImageBuffer.computeHeight(this.data, this.format, this.width); }
    /** Create a new ImageBuffer.
     * @note The ImageBuffer takes ownership of the input Uint8Array.
     * @param data The uncompressed image bytes. Must be a multiple of the width times the number of bytes per pixel specified by the format.
     * @param format The format of the image.
     * @param width The width of the image in pixels.
     * @returns A new ImageBuffer.
     * @throws Error if the length of the Uint8Array is not appropriate for the specified width and format.
     */
    static create(data, format, width) {
        if (!this.isValidData(data, format, width))
            throw new Error("The number of bytes supplied for ImageBuffer do not match its width and format.");
        return new ImageBuffer(data, format, width);
    }
    static isValidData(data, format, width) {
        const height = this.computeHeight(data, format, width);
        return width > 0 && height > 0 && Math.floor(width) === width && Math.floor(height) === height;
    }
    static computeHeight(data, format, width) {
        return data.length / (width * this.getNumBytesPerPixel(format));
    }
    constructor(data, format, width) {
        this.data = data;
        this.format = format;
        this.width = width;
    }
}
exports.ImageBuffer = ImageBuffer;
/** Returns whether the input is a power of two.
 * @note Floating point inputs are truncated.
 * @public
 */
function isPowerOfTwo(num) {
    return 0 === (num & (num - 1));
}
/** Returns the first power-of-two value greater than or equal to the input.
 * @note Floating point inputs are truncated.
 * @public
 */
function nextHighestPowerOfTwo(num) {
    --num;
    for (let i = 1; i < 32; i <<= 1)
        num = num | num >> i;
    return num + 1;
}
/** The format of an ImageSource.
 * @public
 * @extensions
 */
var ImageSourceFormat;
(function (ImageSourceFormat) {
    /** Image data is stored with JPEG compression. */
    ImageSourceFormat[ImageSourceFormat["Jpeg"] = 0] = "Jpeg";
    /** Image data is stored with PNG compression. */
    ImageSourceFormat[ImageSourceFormat["Png"] = 2] = "Png";
    /** Image is stored as an Svg stream.
     * @note SVG is only valid for ImageSources in JavaScript. It *may not* be used for persistent textures.
     */
    ImageSourceFormat[ImageSourceFormat["Svg"] = 3] = "Svg";
})(ImageSourceFormat || (exports.ImageSourceFormat = ImageSourceFormat = {}));
/** Returns true if the numeric `format` value is a valid member of the [[ImageSourceFormat]] enumeration.
 * @public
 */
function isValidImageSourceFormat(format) {
    switch (format) {
        case ImageSourceFormat.Jpeg:
        case ImageSourceFormat.Png:
        case ImageSourceFormat.Svg:
            return true;
        default:
            return false;
    }
}
/** Image data encoded and compressed in either Jpeg or Png format.
 * @public
 */
class ImageSource {
    /** The content of the image, compressed */
    data;
    /** The compression type. */
    format;
    /** Construct a new ImageSource, which takes ownership of the Uint8Array. */
    constructor(data, format) {
        this.data = data;
        this.format = format;
    }
}
exports.ImageSource = ImageSource;
/** Returns true if `source` is a [[BinaryImageSource]].
 * @public
 */
function isBinaryImageSource(source) {
    return source.format !== ImageSourceFormat.Svg && source.data instanceof Uint8Array;
}
//# sourceMappingURL=Image.js.map