import { Frame } from '../lib/frame.js';
import type { SwsFlags } from '../constants/index.js';
import type { HardwareContext } from './hardware.js';
/**
 * Output pixel format for scaled images.
 */
export type ScaledImageFormat = 'rgb' | 'rgba' | 'gray' | 'nv12' | 'yuv420p';
/**
 * Crop region in source pixel coordinates.
 */
export interface ScalerCrop {
    x: number;
    y: number;
    width: number;
    height: number;
}
/**
 * Target dimensions for scaling.
 */
export interface ScalerResize {
    width: number;
    height: number;
}
/**
 * Options for a single scale/crop/convert operation.
 */
export interface ScaleOptions {
    /** Optional crop applied before scaling (source pixel coordinates). */
    crop?: ScalerCrop;
    /** Optional target dimensions. Omit to keep the (cropped) source size. */
    resize?: ScalerResize;
    /** Optional output pixel format. Omit to keep the source format. */
    format?: ScaledImageFormat;
}
/**
 * Options for encoding a frame to JPEG.
 */
export interface JpegOptions {
    /** Optional crop applied before scaling (source pixel coordinates). */
    crop?: ScalerCrop;
    /** Optional target dimensions. Omit to keep the (cropped) source size. */
    resize?: ScalerResize;
    /** JPEG quality from 1 (smallest, lowest quality) to 100 (best). Default 90. */
    quality?: number;
}
/**
 * Options for encoding a frame to PNG.
 */
export interface PngOptions {
    /** Optional crop applied before scaling (source pixel coordinates). */
    crop?: ScalerCrop;
    /** Optional target dimensions. Omit to keep the (cropped) source size. */
    resize?: ScalerResize;
    /** Output color format. Default `'rgb'`. */
    format?: 'rgb' | 'rgba' | 'gray';
}
/**
 * Options for creating a {@link Scaler}.
 */
export interface ScalerOptions {
    /**
     * Hardware context. Required to process hardware frames - crop/scale/convert
     * then run on the GPU and only the small result is downloaded.
     */
    hardware?: HardwareContext | null;
    /** swscale algorithm flags (SWS_*) for the software path. Defaults to `SWS_BILINEAR`. */
    flags?: SwsFlags;
    /**
     * Maximum number of cached hardware filter graphs (one per distinct output
     * configuration). Least-recently-used graphs are evicted beyond this. Default 16.
     */
    maxCacheSize?: number;
}
/**
 * High-level image scaler, cropper, and pixel-format converter.
 *
 * Scales, crops, and converts decoded frames to raw pixel buffers or encoded
 * JPEG/PNG images. Built for the detection/thumbnail/snapshot workload: one
 * instance pools its swscale contexts, GPU filter graphs, and encoders, so
 * reusing it for every frame and every crop avoids per-frame allocation.
 * Software frames are scaled with swscale; hardware frames are cropped, scaled,
 * and converted on the GPU with only the small result downloaded.
 *
 * @example
 * ```typescript
 * import { Scaler } from 'node-av/api';
 *
 * using scaler = new Scaler({ hardware });
 *
 * // Scale + convert to RGB (on the GPU for hardware frames)
 * const rgb = await scaler.toBuffer(frame, { resize: { width: 640, height: 360 }, format: 'rgb' });
 *
 * // Crop a detected region and encode a snapshot
 * const jpeg = await scaler.toJpeg(frame, { crop: { x, y, width: w, height: h }, quality: 85 });
 * ```
 *
 * @see {@link EncoderPool} For pooled image encoders
 * @see {@link FilterAPI} For streaming filtergraphs
 */
export declare class Scaler implements Disposable {
    private native;
    private hardware?;
    private flags;
    private maxCacheSize;
    private graphs;
    private jpegPool?;
    private pngPool?;
    private downloadFrame?;
    private disposed;
    /**
     * Create a new scaler.
     *
     * @param options - Scaler options
     *
     * @example
     * ```typescript
     * using scaler = new Scaler({ hardware: HardwareContext.auto() });
     * ```
     */
    constructor(options?: ScalerOptions);
    /**
     * Scale, crop, and/or convert a frame and return the raw pixel data.
     *
     * The returned buffer is tightly packed (no row padding). For planar formats
     * (`nv12`, `yuv420p`) planes are concatenated.
     *
     * @param frame - Source frame (software or hardware; hardware frames are processed on the GPU and downloaded)
     *
     * @param options - Crop, resize, and format options
     *
     * @returns Tightly packed pixel data
     *
     * @throws {FFmpegError} If scaling fails
     *
     * @example
     * ```typescript
     * const gray = await scaler.toBuffer(frame, { resize: { width: 320, height: 180 }, format: 'gray' });
     * ```
     *
     * @see {@link toBufferSync} For synchronous version
     */
    toBuffer(frame: Frame, options?: ScaleOptions): Promise<Buffer>;
    /**
     * Scale, crop, and/or convert a frame and return the raw pixel data.
     * Synchronous version of toBuffer.
     *
     * @param frame - Source frame (software or hardware; hardware frames are processed on the GPU and downloaded)
     *
     * @param options - Crop, resize, and format options
     *
     * @returns Tightly packed pixel data
     *
     * @throws {FFmpegError} If scaling fails
     *
     * @example
     * ```typescript
     * const gray = scaler.toBufferSync(frame, { resize: { width: 320, height: 180 }, format: 'gray' });
     * ```
     *
     * @see {@link toBuffer} For async version
     */
    toBufferSync(frame: Frame, options?: ScaleOptions): Buffer;
    /**
     * Scale/crop a frame and encode it to a JPEG image.
     *
     * The encoder is pooled per output size and reused across calls - no encoder is
     * rebuilt per snapshot. Hardware frames are scaled on the GPU and downloaded;
     * software frames are scaled with swscale.
     *
     * @param frame - Source frame (software or hardware)
     *
     * @param options - Crop, resize, and quality options
     *
     * @returns Encoded JPEG bytes
     *
     * @throws {FFmpegError} If scaling or encoding fails
     *
     * @example
     * ```typescript
     * const jpeg = await scaler.toJpeg(frame, { resize: { width: 1280, height: 720 }, quality: 85 });
     * await writeFile('snapshot.jpg', jpeg);
     * ```
     *
     * @see {@link toJpegSync} For synchronous version
     */
    toJpeg(frame: Frame, options?: JpegOptions): Promise<Buffer>;
    /**
     * Scale/crop a frame and encode it to a JPEG image.
     * Synchronous version of toJpeg.
     *
     * @param frame - Source frame (software or hardware)
     *
     * @param options - Crop, resize, and quality options
     *
     * @returns Encoded JPEG bytes
     *
     * @throws {FFmpegError} If scaling or encoding fails
     *
     * @example
     * ```typescript
     * const jpeg = scaler.toJpegSync(frame, { resize: { width: 1280, height: 720 }, quality: 85 });
     * ```
     *
     * @see {@link toJpeg} For async version
     */
    toJpegSync(frame: Frame, options?: JpegOptions): Buffer;
    /**
     * Scale/crop a frame and encode it to a PNG image.
     *
     * The encoder is pooled per output size/format and reused across calls. Hardware
     * frames are scaled on the GPU and downloaded; software frames use swscale.
     *
     * @param frame - Source frame (software or hardware)
     *
     * @param options - Crop, resize, and color-format options
     *
     * @returns Encoded PNG bytes
     *
     * @throws {FFmpegError} If scaling or encoding fails
     *
     * @example
     * ```typescript
     * const png = await scaler.toPng(frame, { crop: { x, y, width: w, height: h } });
     * await writeFile('region.png', png);
     * ```
     *
     * @see {@link toPngSync} For synchronous version
     */
    toPng(frame: Frame, options?: PngOptions): Promise<Buffer>;
    /**
     * Scale/crop a frame and encode it to a PNG image.
     * Synchronous version of toPng.
     *
     * @param frame - Source frame (software or hardware)
     *
     * @param options - Crop, resize, and color-format options
     *
     * @returns Encoded PNG bytes
     *
     * @throws {FFmpegError} If scaling or encoding fails
     *
     * @example
     * ```typescript
     * const png = scaler.toPngSync(frame, { crop: { x, y, width: w, height: h } });
     * ```
     *
     * @see {@link toPng} For async version
     */
    toPngSync(frame: Frame, options?: PngOptions): Buffer;
    /**
     * Release all pooled scaling contexts, graphs, and frames.
     *
     * @example
     * ```typescript
     * scaler.close();
     * ```
     */
    close(): void;
    /**
     * Download a hardware frame to system memory (no hardware context available).
     *
     * Reuses a single target frame across calls. The frame's own hwframe context
     * selects a supported software format.
     *
     * @param frame - Hardware source frame
     *
     * @returns Software frame
     *
     * @throws {FFmpegError} If the transfer fails
     *
     * @internal
     */
    private downloadToSoftware;
    /**
     * Synchronous version of downloadToSoftware.
     *
     * @param frame - Hardware source frame
     *
     * @returns Software frame
     *
     * @throws {FFmpegError} If the transfer fails
     *
     * @internal
     */
    private downloadToSoftwareSync;
    /**
     * Lazily allocate and reset the reused download target frame.
     *
     * @returns The cleared download frame
     *
     * @internal
     */
    private prepareDownloadTarget;
    /**
     * Scale/crop/convert a frame through a cached filter graph and return the
     * resulting frame (caller must free it).
     *
     * Software frames are scaled with swscale filters; hardware frames are
     * cropped/scaled/converted on the GPU and downloaded. The crop region is
     * reconfigured per frame via a runtime command on a graph shared per output
     * size (except OpenCL, where the crop is baked in).
     *
     * @param frame - Source frame (software, or hardware with a hardware context)
     *
     * @param crop - Crop region, or undefined for the full frame
     *
     * @param resize - Target dimensions, or undefined to keep the cropped size
     *
     * @param format - Output pixel format
     *
     * @returns The scaled output frame (caller frees)
     *
     * @throws {Error} If the crop is out of bounds or the graph produces no frame
     *
     * @internal
     */
    private toFrame;
    /**
     * Synchronous version of toFrame.
     *
     * @param frame - Source frame (software, or hardware with a hardware context)
     *
     * @param crop - Crop region, or undefined for the full frame
     *
     * @param resize - Target dimensions, or undefined to keep the cropped size
     *
     * @param format - Output pixel format
     *
     * @returns The scaled output frame (caller frees)
     *
     * @internal
     */
    private toFrameSync;
    /**
     * Resolve (and, on demand, build) the cached filter graph for a frame, applying
     * the crop reconfiguration. Shared by the sync and async scaling paths; all of
     * this work (parse, config, sendCommand) is synchronous.
     *
     * @param frame - Source frame (software, or hardware with a hardware context)
     *
     * @param crop - Crop region, or undefined for the full frame
     *
     * @param resize - Target dimensions, or undefined to keep the cropped size
     *
     * @param format - Output pixel format
     *
     * @returns The cached graph entry, ready to process the frame
     *
     * @throws {Error} If the crop is out of bounds
     *
     * @internal
     */
    private resolveGraph;
    /**
     * Tag a frame for MJPEG encoding: full color range and a per-frame quality.
     *
     * MJPEG quality is carried on the frame (the encoder pool sets the QSCALE flag),
     * so one pooled encoder serves every quality for a given output size.
     *
     * @param frame - Frame about to be JPEG-encoded
     *
     * @param quality - Quality from 1 (worst) to 100 (best)
     *
     * @internal
     */
    private prepareJpegFrame;
    /**
     * The lazily created MJPEG encoder pool (QSCALE flag set for per-frame quality).
     *
     * @returns The JPEG encoder pool
     *
     * @internal
     */
    private getJpegPool;
    /**
     * The lazily created PNG encoder pool.
     *
     * @returns The PNG encoder pool
     *
     * @internal
     */
    private getPngPool;
    /**
     * Build a crop+scale+convert graph.
     *
     * For software frames this is `crop,scale,format`. For hardware frames the crop
     * filter sets crop metadata that the hardware scaler (scale_vt/scale_cuda/
     * scale_vaapi) applies on the GPU; the result is kept in NV12, downloaded, and
     * converted on the CPU. When `commandable` the crop is a labeled instance
     * (`crop@sc`) whose initial region is `crop` but which is re-aimed per frame via
     * `sendCommand`. Otherwise (OpenCL) the crop is fixed in the graph.
     *
     * @param isHw - Whether the input is a hardware frame
     *
     * @param outW - Output width
     *
     * @param outH - Output height
     *
     * @param format - Output pixel format
     *
     * @param crop - Initial crop region
     *
     * @param commandable - Whether the crop can be reconfigured at runtime
     *
     * @returns Filtergraph description
     *
     * @internal
     */
    private buildGraph;
    /**
     * Insert a graph, evicting the least-recently-used entry if over capacity.
     *
     * @param key - Operation-configuration key
     *
     * @param entry - Graph entry to cache
     *
     * @internal
     */
    private cacheSet;
    /**
     * Dispose of the scaler (for `using` statements).
     *
     * @example
     * ```typescript
     * using scaler = new Scaler();
     * // ... use scaler ...
     * // automatically disposed at end of scope
     * ```
     */
    [Symbol.dispose](): void;
}
