"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PixelCollection = void 0;
const image_magick_1 = require("../image-magick");
const exception_1 = require("../exception/exception");
const native_instance_1 = require("../native-instance");
const string_1 = require("../native/string");
class PixelCollection extends native_instance_1.NativeInstance {
    constructor(image) {
        const instance = exception_1.Exception.usePointer((exception) => {
            return image_magick_1.ImageMagick._api._PixelCollection_Create(image._instance, exception);
        });
        const disposeMethod = image_magick_1.ImageMagick._api._PixelCollection_Dispose;
        super(instance, disposeMethod);
        this.image = image;
    }
    static _create(image) {
        return new PixelCollection(image);
    }
    static _use(image, func) {
        const pixels = new PixelCollection(image);
        try {
            return func(pixels);
        }
        finally {
            pixels.dispose();
        }
    }
    static _map(image, mapping, func) {
        const pixels = new PixelCollection(image);
        try {
            pixels.use(0, 0, image.width, image.height, mapping, (instance) => {
                func(instance);
            });
        }
        finally {
            pixels.dispose();
        }
    }
    getArea(x, y, width, height) {
        return exception_1.Exception.usePointer((exception) => {
            const instance = image_magick_1.ImageMagick._api._PixelCollection_GetArea(this._instance, x, y, width, height, exception);
            const count = width * height * this.image.channelCount;
            return image_magick_1.ImageMagick._api.HEAPU8.subarray(instance, instance + count);
        });
    }
    toByteArray(x, y, width, height, mapping) {
        return this.use(x, y, width, height, mapping, (instance) => {
            return PixelCollection.createArray(instance, width, height, mapping.length);
        });
    }
    static createArray(instance, width, height, channelCount) {
        if (instance === 0)
            return null;
        try {
            const count = width * height * channelCount;
            return image_magick_1.ImageMagick._api.HEAPU8.slice(instance, instance + count);
        }
        finally {
            image_magick_1.ImageMagick._api._MagickMemory_Relinquish(instance);
        }
    }
    use(x, y, width, height, mapping, func) {
        return string_1._withString(mapping, (mappingPtr) => {
            return exception_1.Exception.use((exception) => {
                const instance = image_magick_1.ImageMagick._api._PixelCollection_ToByteArray(this._instance, x, y, width, height, mappingPtr, exception.ptr);
                return exception.check(() => {
                    const result = func(instance);
                    image_magick_1.ImageMagick._api._MagickMemory_Relinquish(instance);
                    return result;
                }, () => {
                    image_magick_1.ImageMagick._api._MagickMemory_Relinquish(instance);
                    return null;
                });
            });
        });
    }
}
exports.PixelCollection = PixelCollection;
