"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MagickImage = void 0;
const alpha_option_1 = require("./alpha-option");
const channels_1 = require("./channels");
const color_space_1 = require("./color-space");
const composite_operator_1 = require("./composite-operator");
const exception_1 = require("./internal/exception/exception");
const gravity_1 = require("./gravity");
const image_magick_1 = require("./image-magick");
const image_profile_1 = require("./profiles/image-profile");
const magick_image_collection_1 = require("./magick-image-collection");
const native_instance_1 = require("./internal/native-instance");
const magick_color_1 = require("./magick-color");
const magick_format_1 = require("./magick-format");
const magick_geometry_1 = require("./magick-geometry");
const magick_read_settings_1 = require("./settings/magick-read-settings");
const magick_rectangle_1 = require("./internal/magick-rectangle");
const magick_settings_1 = require("./settings/magick-settings");
const percentage_1 = require("./percentage");
const pixel_collection_1 = require("./pixels/pixel-collection");
const point_1 = require("./point");
const pointer_1 = require("./internal/pointer/pointer");
const quantum_1 = require("./quantum");
const string_info_1 = require("./internal/string-info");
const string_1 = require("./internal/native/string");
const array_1 = require("./internal/native/array");
class MagickImage extends native_instance_1.NativeInstance {
    constructor(instance, settings) {
        super(instance, image_magick_1.ImageMagick._api._MagickImage_Dispose);
        this.toString = () => `${this.format} ${this.width}x${this.height} ${this.depth}-bit ${color_space_1.ColorSpace[this.colorSpace]}`;
        this._settings = settings;
    }
    get artifactNames() {
        const artifactNames = [];
        image_magick_1.ImageMagick._api._MagickImage_ResetArtifactIterator(this._instance);
        let name = image_magick_1.ImageMagick._api._MagickImage_GetNextArtifactName(this._instance);
        while (name !== 0) {
            artifactNames.push(image_magick_1.ImageMagick._api.UTF8ToString(name));
            name = image_magick_1.ImageMagick._api._MagickImage_GetNextArtifactName(this._instance);
        }
        return artifactNames;
    }
    get backgroundColor() {
        const colorPtr = image_magick_1.ImageMagick._api._MagickImage_BackgroundColor_Get(this._instance);
        return magick_color_1.MagickColor._create(colorPtr);
    }
    set backgroundColor(value) {
        value._use(valuePtr => {
            image_magick_1.ImageMagick._api._MagickImage_BackgroundColor_Set(this._instance, valuePtr);
        });
    }
    get channelCount() { return image_magick_1.ImageMagick._api._MagickImage_ChannelCount_Get(this._instance); }
    get colorSpace() {
        return exception_1.Exception.usePointer(exception => {
            return image_magick_1.ImageMagick._api._MagickImage_ColorSpace_Get(this._instance, exception);
        });
    }
    set colorSpace(value) {
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_ColorSpace_Set(this._instance, value, exception);
        });
    }
    get depth() { return image_magick_1.ImageMagick._api._MagickImage_Depth_Get(this._instance); }
    set depth(value) { image_magick_1.ImageMagick._api._MagickImage_Depth_Set(this._instance, value); }
    get format() { return string_1._createString(image_magick_1.ImageMagick._api._MagickImage_Format_Get(this._instance), ''); }
    set format(value) { string_1._withString(value, instance => image_magick_1.ImageMagick._api._MagickImage_Format_Set(this._instance, instance)); }
    get hasAlpha() {
        return exception_1.Exception.usePointer(exception => {
            return this.toBool(image_magick_1.ImageMagick._api._MagickImage_HasAlpha_Get(this._instance, exception));
        });
    }
    set hasAlpha(value) {
        exception_1.Exception.usePointer(exception => {
            if (value)
                this.alpha(alpha_option_1.AlphaOption.Opaque);
            image_magick_1.ImageMagick._api._MagickImage_HasAlpha_Set(this._instance, this.fromBool(value), exception);
        });
    }
    get height() { return image_magick_1.ImageMagick._api._MagickImage_Height_Get(this._instance); }
    get orientation() { return image_magick_1.ImageMagick._api._MagickImage_Orientation_Get(this._instance); }
    set orientation(value) { image_magick_1.ImageMagick._api._MagickImage_Orientation_Set(this._instance, value); }
    get quality() { return image_magick_1.ImageMagick._api._MagickImage_Quality_Get(this._instance); }
    set quality(value) {
        let quality = value < 1 ? 1 : value;
        quality = quality > 100 ? 100 : quality;
        image_magick_1.ImageMagick._api._MagickImage_Quality_Set(this._instance, quality);
        this._settings._quality = quality;
    }
    get signature() {
        return exception_1.Exception.usePointer(exception => {
            return string_1._createString(image_magick_1.ImageMagick._api._MagickImage_Signature_Get(this._instance, exception));
        });
    }
    get virtualPixelMethod() {
        return exception_1.Exception.usePointer(exception => {
            return image_magick_1.ImageMagick._api._MagickImage_VirtualPixelMethod_Get(this._instance, exception);
        });
    }
    set virtualPixelMethod(value) {
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_VirtualPixelMethod_Set(this._instance, value, exception);
        });
    }
    get width() { return image_magick_1.ImageMagick._api._MagickImage_Width_Get(this._instance); }
    alpha(value) {
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_SetAlpha(this._instance, value, exception);
        });
    }
    autoOrient() {
        exception_1.Exception.use(exception => {
            const instance = image_magick_1.ImageMagick._api._MagickImage_AutoOrient(this._instance, exception.ptr);
            this._setInstance(instance, exception);
        });
    }
    blur(radiusOrChannel, sigma, channels) {
        let radius = 0;
        const sigmaValue = this.valueOrDefault(sigma, 1);
        let channelsValue = this.valueOrDefault(channels, channels_1.Channels.Composite);
        if (typeof radiusOrChannel === 'number')
            radius = radiusOrChannel;
        else if (radiusOrChannel !== undefined)
            channelsValue = radiusOrChannel;
        exception_1.Exception.use(exception => {
            const instance = image_magick_1.ImageMagick._api._MagickImage_Blur(this._instance, radius, sigmaValue, channelsValue, exception.ptr);
            this._setInstance(instance, exception);
        });
    }
    channelOffset(pixelChannel) {
        if (!image_magick_1.ImageMagick._api._MagickImage_HasChannel(this._instance, pixelChannel))
            return -1;
        return image_magick_1.ImageMagick._api._MagickImage_ChannelOffset(this._instance, pixelChannel);
    }
    clahe(xTiles, yTiles, numberBins, clipLimit) {
        exception_1.Exception.usePointer(exception => {
            const xTilesValue = xTiles instanceof percentage_1.Percentage ? xTiles.multiply(this.width) : xTiles;
            const yTilesValue = yTiles instanceof percentage_1.Percentage ? yTiles.multiply(this.height) : yTiles;
            image_magick_1.ImageMagick._api._MagickImage_Clahe(this._instance, xTilesValue, yTilesValue, numberBins, clipLimit, exception);
        });
    }
    clone(func) {
        return exception_1.Exception.usePointer(exception => {
            const image = new MagickImage(image_magick_1.ImageMagick._api._MagickImage_Clone(this._instance, exception), this._settings._clone());
            try {
                return func(image);
            }
            finally {
                image.dispose();
            }
        });
    }
    colorAlpha(color) {
        if (!this.hasAlpha)
            return;
        const canvas = MagickImage.create();
        canvas.read(color, this.width, this.height);
        canvas.composite(this, composite_operator_1.CompositeOperator.SrcOver, new point_1.Point(0, 0));
        this._instance = canvas._instance;
    }
    compare(image, metric, channels) {
        return exception_1.Exception.usePointer(exception => {
            const compareChannels = channels !== undefined ? channels : channels_1.Channels.Composite;
            return image_magick_1.ImageMagick._api._MagickImage_CompareDistortion(this._instance, image._instance, metric, compareChannels, exception);
        });
    }
    composite(image, composeOrPoint, pointOrArgsOrChannels, channelsOrArgs, channels) {
        let x = 0;
        let y = 0;
        let compose = composite_operator_1.CompositeOperator.In;
        let compositeChannels = channels_1.Channels.Default;
        let args = null;
        if (composeOrPoint instanceof point_1.Point) {
            x = composeOrPoint.x;
            y = composeOrPoint.y;
        }
        else if (composeOrPoint !== undefined) {
            compose = composeOrPoint;
        }
        if (pointOrArgsOrChannels instanceof point_1.Point) {
            x = pointOrArgsOrChannels.x;
            y = pointOrArgsOrChannels.y;
        }
        else if (typeof pointOrArgsOrChannels === 'string') {
            args = pointOrArgsOrChannels;
        }
        else if (pointOrArgsOrChannels !== undefined) {
            compositeChannels = pointOrArgsOrChannels;
        }
        if (typeof channelsOrArgs === 'string')
            args = channelsOrArgs;
        else if (channelsOrArgs !== undefined)
            compositeChannels = channelsOrArgs;
        if (channels !== undefined)
            compositeChannels = channels;
        if (args !== null)
            this.setArtifact('compose:args', args);
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_Composite(this._instance, image._instance, x, y, compose, compositeChannels, exception);
        });
        if (args !== null)
            this.removeArtifact('compose:args');
    }
    compositeGravity(image, gravity, composeOrPoint, pointOrArgsOrChannels, channelsOrArgs, channels) {
        let x = 0;
        let y = 0;
        let compose = composite_operator_1.CompositeOperator.In;
        let compositeChannels = channels_1.Channels.Default;
        let args = null;
        if (composeOrPoint instanceof point_1.Point) {
            x = composeOrPoint.x;
            y = composeOrPoint.y;
        }
        else if (composeOrPoint !== undefined) {
            compose = composeOrPoint;
        }
        if (pointOrArgsOrChannels instanceof point_1.Point) {
            x = pointOrArgsOrChannels.x;
            y = pointOrArgsOrChannels.y;
        }
        else if (typeof pointOrArgsOrChannels === 'string') {
            args = pointOrArgsOrChannels;
        }
        else if (pointOrArgsOrChannels !== undefined) {
            compositeChannels = pointOrArgsOrChannels;
        }
        if (typeof channelsOrArgs === 'string')
            args = channelsOrArgs;
        else if (channelsOrArgs !== undefined)
            compositeChannels = channelsOrArgs;
        if (channels !== undefined)
            compositeChannels = channels;
        if (args !== null)
            this.setArtifact('compose:args', args);
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_CompositeGravity(this._instance, image._instance, gravity, x, y, compose, compositeChannels, exception);
        });
        if (args !== null)
            this.removeArtifact('compose:args');
    }
    static create() {
        return new MagickImage(MagickImage.createInstance(), new magick_settings_1.MagickSettings());
    }
    deskew(threshold) {
        exception_1.Exception.use(exception => {
            const instance = image_magick_1.ImageMagick._api._MagickImage_Deskew(this._instance, threshold.toQuantum(), exception.ptr);
            this._setInstance(instance, exception);
        });
        const angle = Number(this.getArtifact('deskew:angle'));
        return isNaN(angle) ? 0.0 : angle;
    }
    distort(method, settingsOrParams, params) {
        let distortArgs;
        let bestFit = 0;
        let settings = null;
        if (settingsOrParams instanceof Array) {
            distortArgs = settingsOrParams;
        }
        else if (params instanceof Array) {
            distortArgs = params;
            settings = settingsOrParams;
            bestFit = settings.bestFit ? 1 : 0;
            settings._setArtifacts(this);
        }
        else {
            distortArgs = [];
        }
        exception_1.Exception.use(exception => {
            array_1._withDoubleArray(distortArgs, (distortArgsPtr) => {
                const instance = image_magick_1.ImageMagick._api._MagickImage_Distort(this._instance, method, bestFit, distortArgsPtr, distortArgs.length, exception.ptr);
                this._setInstance(instance, exception);
            });
        });
        if (settings !== null)
            settings._removeArtifacts(this);
    }
    evaluate(channels, operatorOrGeometry, valueOrPercentageOrOperator, valueOrPercentage) {
        if (typeof operatorOrGeometry === 'number') {
            const operator = operatorOrGeometry;
            const value = typeof valueOrPercentageOrOperator === 'number' ? valueOrPercentageOrOperator : valueOrPercentageOrOperator.toQuantum();
            exception_1.Exception.usePointer(exception => {
                image_magick_1.ImageMagick._api._MagickImage_EvaluateOperator(this._instance, channels, operator, value, exception);
            });
        }
        else if (valueOrPercentage !== undefined) {
            if (typeof valueOrPercentageOrOperator !== 'number')
                throw new Error();
            const geometry = operatorOrGeometry;
            const operator = valueOrPercentageOrOperator;
            const value = typeof valueOrPercentage === 'number' ? valueOrPercentage : valueOrPercentage.toQuantum();
            if (geometry.isPercentage)
                throw new Error('percentage is not supported');
            exception_1.Exception.usePointer(exception => {
                magick_rectangle_1.MagickRectangle.use(this, geometry, rectangle => {
                    image_magick_1.ImageMagick._api._MagickImage_EvaluateGeometry(this._instance, channels, rectangle, operator, value, exception);
                });
            });
        }
    }
    extent(geometryOrWidth, widthOrGravityOrBackgroundColor, backgroundColorOrGravity) {
        let gravity = gravity_1.Gravity.Undefined;
        let geometry;
        if (geometryOrWidth instanceof magick_geometry_1.MagickGeometry)
            geometry = geometryOrWidth;
        else if (typeof widthOrGravityOrBackgroundColor === 'number')
            geometry = new magick_geometry_1.MagickGeometry(geometryOrWidth, widthOrGravityOrBackgroundColor);
        if (widthOrGravityOrBackgroundColor instanceof magick_color_1.MagickColor)
            this.backgroundColor = widthOrGravityOrBackgroundColor;
        else if (widthOrGravityOrBackgroundColor !== undefined)
            gravity = widthOrGravityOrBackgroundColor;
        if (backgroundColorOrGravity instanceof magick_color_1.MagickColor)
            this.backgroundColor = backgroundColorOrGravity;
        else if (backgroundColorOrGravity !== undefined)
            gravity = backgroundColorOrGravity;
        exception_1.Exception.use(exception => {
            string_1._withString(geometry.toString(), geometryPtr => {
                const instance = image_magick_1.ImageMagick._api._MagickImage_Extent(this._instance, geometryPtr, gravity, exception.ptr);
                this._setInstance(instance, exception);
            });
        });
    }
    getArtifact(name) {
        return string_1._withString(name, namePtr => {
            const value = image_magick_1.ImageMagick._api._MagickImage_GetArtifact(this._instance, namePtr);
            return string_1._createString(value);
        });
    }
    getProfile(name) {
        return string_1._withString(name, namePtr => {
            const value = image_magick_1.ImageMagick._api._MagickImage_GetProfile(this._instance, namePtr);
            const data = string_info_1.StringInfo.toArray(value);
            if (data === null)
                return null;
            return new image_profile_1.ImageProfile(name, data);
        });
    }
    getWriteMask(func) {
        return exception_1.Exception.usePointer(exception => {
            const instance = image_magick_1.ImageMagick._api._MagickImage_GetWriteMask(this._instance, exception);
            const image = instance === 0 ? null : new MagickImage(instance, new magick_settings_1.MagickSettings());
            return func(image);
        });
    }
    getPixels(func) {
        return pixel_collection_1.PixelCollection._use(this, (pixels) => {
            return func(pixels);
        });
    }
    level(channelsOrBlackPoint, blackPointOrWhitePoint, whitePointPercentageOrGamma, gamma) {
        let channels = channels_1.Channels.Composite;
        let blackPoint;
        let whitePoint;
        let gammaValue = gamma !== undefined ? gamma : 1.0;
        if (typeof channelsOrBlackPoint === 'number') {
            channels = channelsOrBlackPoint;
            blackPoint = blackPointOrWhitePoint;
            if (whitePointPercentageOrGamma instanceof percentage_1.Percentage)
                whitePoint = whitePointPercentageOrGamma;
        }
        else {
            blackPoint = channelsOrBlackPoint;
            whitePoint = blackPointOrWhitePoint;
            if (typeof whitePointPercentageOrGamma === 'number')
                gammaValue = whitePointPercentageOrGamma;
        }
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_Level(this._instance, blackPoint.toDouble(), whitePoint.toQuantum(), gammaValue, channels, exception);
        });
    }
    modulate(brightness, saturation, hue) {
        const saturationPercentage = saturation === undefined ? new percentage_1.Percentage(100) : saturation;
        const huePercentage = hue === undefined ? new percentage_1.Percentage(100) : hue;
        exception_1.Exception.usePointer(exception => {
            const modulate = `${brightness.toDouble()}/${saturationPercentage.toDouble()}/${huePercentage.toDouble()}`;
            string_1._withString(modulate, modulatePtr => {
                image_magick_1.ImageMagick._api._MagickImage_Modulate(this._instance, modulatePtr, exception);
            });
        });
    }
    read(fileNameOrArrayOrColor, settingsOrWidth, height) {
        exception_1.Exception.use(exception => {
            if (fileNameOrArrayOrColor instanceof Uint8Array) {
                const readSettings = settingsOrWidth instanceof magick_read_settings_1.MagickReadSettings ? settingsOrWidth : magick_read_settings_1.MagickReadSettings._createFrom(this._settings);
                this.readFromArray(fileNameOrArrayOrColor, readSettings, exception);
            }
            else {
                const readSettings = settingsOrWidth instanceof magick_read_settings_1.MagickReadSettings ? settingsOrWidth : magick_read_settings_1.MagickReadSettings._createFrom(this._settings);
                if (typeof fileNameOrArrayOrColor === 'string') {
                    readSettings._fileName = fileNameOrArrayOrColor;
                }
                else if (fileNameOrArrayOrColor instanceof magick_color_1.MagickColor) {
                    readSettings._fileName = 'xc:' + fileNameOrArrayOrColor.toShortString();
                    readSettings.width = typeof settingsOrWidth === 'number' ? settingsOrWidth : 0;
                    readSettings.height = typeof height === 'number' ? height : 0;
                }
                readSettings._use(settings => {
                    const instance = image_magick_1.ImageMagick._api._MagickImage_ReadFile(settings._instance, exception.ptr);
                    this._setInstance(instance, exception);
                });
            }
        });
    }
    readFromCanvas(canvas) {
        const ctx = canvas.getContext('2d');
        if (ctx === null)
            return;
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const settings = new magick_read_settings_1.MagickReadSettings();
        settings.format = magick_format_1.MagickFormat.Rgba;
        settings.width = canvas.width;
        settings.height = canvas.height;
        exception_1.Exception.use(exception => {
            this.readFromArray(imageData.data, settings, exception);
        });
    }
    removeArtifact(name) {
        string_1._withString(name, namePtr => {
            image_magick_1.ImageMagick._api._MagickImage_RemoveArtifact(this._instance, namePtr);
        });
    }
    removeWriteMask() {
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_SetWriteMask(this._instance, 0, exception);
        });
    }
    resize(widthOrGeometry, height) {
        const geometry = typeof widthOrGeometry === 'number' ? new magick_geometry_1.MagickGeometry(widthOrGeometry, height) : widthOrGeometry;
        exception_1.Exception.use(exception => {
            string_1._withString(geometry.toString(), geometryPtr => {
                const instance = image_magick_1.ImageMagick._api._MagickImage_Resize(this._instance, geometryPtr, exception.ptr);
                this._setInstance(instance, exception);
            });
        });
    }
    sharpen(radius, sigma, channels) {
        const radiusValue = radius !== undefined ? radius : 0.0;
        const sigmaValue = sigma !== undefined ? sigma : 1.0;
        const channelsValue = channels !== undefined ? channels : channels_1.Channels.Composite;
        exception_1.Exception.use(exception => {
            const instance = image_magick_1.ImageMagick._api._MagickImage_Sharpen(this._instance, radiusValue, sigmaValue, channelsValue, exception.ptr);
            this._setInstance(instance, exception);
        });
    }
    sigmoidalContrast(sharpenOrConstract, contrastOrMidpointOrPercentage, midpointOrPercentage) {
        let sharpen;
        let contrast;
        let midpoint;
        if (midpointOrPercentage !== undefined) {
            if (typeof sharpenOrConstract !== 'number')
                sharpen = sharpenOrConstract;
            if (typeof contrastOrMidpointOrPercentage === 'number')
                contrast = contrastOrMidpointOrPercentage;
            if (typeof midpointOrPercentage === 'number')
                midpoint = midpointOrPercentage;
            else
                midpoint = midpointOrPercentage.multiply(quantum_1.Quantum.max);
        }
        else {
            if (typeof sharpenOrConstract === 'number') {
                sharpen = true;
                contrast = sharpenOrConstract;
                if (typeof contrastOrMidpointOrPercentage === 'number')
                    midpoint = contrastOrMidpointOrPercentage;
                else if (contrastOrMidpointOrPercentage !== undefined)
                    midpoint = contrastOrMidpointOrPercentage.multiply(quantum_1.Quantum.max);
                else
                    midpoint = quantum_1.Quantum.max * 0.5;
            }
            else {
                sharpen = sharpenOrConstract;
                if (typeof contrastOrMidpointOrPercentage === 'number')
                    contrast = contrastOrMidpointOrPercentage;
                midpoint = quantum_1.Quantum.max * 0.5;
            }
        }
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_SigmoidalContrast(this._instance, this.fromBool(sharpen), contrast, midpoint, exception);
        });
    }
    separate(func, channels) {
        return exception_1.Exception.use(exception => {
            const images = image_magick_1.ImageMagick._api._MagickImage_Separate(this._instance, channels !== null && channels !== void 0 ? channels : channels_1.Channels.All, exception.ptr);
            const collection = magick_image_collection_1.MagickImageCollection._createFromImages(images, this._settings._clone());
            return collection._use(func);
        });
    }
    setArtifact(name, value) {
        let strValue;
        if (typeof value === 'string') {
            strValue = value;
        }
        else {
            strValue = this.fromBool(value).toString();
        }
        string_1._withString(name, namePtr => {
            string_1._withString(strValue, valuePtr => {
                image_magick_1.ImageMagick._api._MagickImage_SetArtifact(this._instance, namePtr, valuePtr);
            });
        });
    }
    setWriteMask(image) {
        exception_1.Exception.usePointer(exception => {
            image_magick_1.ImageMagick._api._MagickImage_SetWriteMask(this._instance, image._instance, exception);
        });
    }
    write(func, format) {
        let bytes = new Uint8Array();
        exception_1.Exception.use(exception => {
            pointer_1.Pointer.use(pointer => {
                if (format !== undefined)
                    this._settings.format = format;
                this._settings._use(settings => {
                    let data = 0;
                    try {
                        data = image_magick_1.ImageMagick._api._MagickImage_WriteBlob(this._instance, settings._instance, pointer.ptr, exception.ptr);
                        bytes = image_magick_1.ImageMagick._api.HEAPU8.subarray(data, data + pointer.value);
                    }
                    catch (_a) {
                        if (data !== 0)
                            image_magick_1.ImageMagick._api._MagickMemory_Relinquish(data);
                    }
                });
            });
        });
        return func(bytes);
    }
    writeToCanvas(canvas) {
        canvas.width = this.width;
        canvas.height = this.height;
        const ctx = canvas.getContext('2d');
        if (ctx === null)
            return;
        pixel_collection_1.PixelCollection._map(this, 'RGBA', q => {
            const imageData = ctx.createImageData(this.width, this.height);
            let p = 0;
            for (let y = 0; y < this.height; y++) {
                for (let x = 0; x < this.width; x++) {
                    imageData.data[p++] = image_magick_1.ImageMagick._api.HEAPU8[q++];
                    imageData.data[p++] = image_magick_1.ImageMagick._api.HEAPU8[q++];
                    imageData.data[p++] = image_magick_1.ImageMagick._api.HEAPU8[q++];
                    imageData.data[p++] = image_magick_1.ImageMagick._api.HEAPU8[q++];
                }
            }
            ctx.putImageData(imageData, 0, 0);
        });
    }
    static _createFromImage(instance, settings) {
        return new MagickImage(instance, settings);
    }
    _instanceNotInitialized() {
        throw new Error('no image has been read');
    }
    static _use(func) {
        const image = MagickImage.create();
        try {
            return func(image);
        }
        finally {
            image.dispose();
        }
    }
    static createInstance() {
        return exception_1.Exception.usePointer(exception => {
            return image_magick_1.ImageMagick._api._MagickImage_Create(0, exception);
        });
    }
    fromBool(value) {
        return value ? 1 : 0;
    }
    readFromArray(array, readSettings, exception) {
        readSettings._use(settings => {
            const length = array.byteLength;
            let data = 0;
            try {
                data = image_magick_1.ImageMagick._api._malloc(length);
                image_magick_1.ImageMagick._api.HEAPU8.set(array, data);
                const instance = image_magick_1.ImageMagick._api._MagickImage_ReadBlob(settings._instance, data, 0, length, exception.ptr);
                this._setInstance(instance, exception);
            }
            finally {
                if (data !== 0)
                    image_magick_1.ImageMagick._api._free(data);
            }
        });
    }
    toBool(value) {
        return value === 1;
    }
    valueOrDefault(value, defaultValue) {
        if (value === undefined)
            return defaultValue;
        return value;
    }
}
exports.MagickImage = MagickImage;
