/**
 * Image processing utilities for multimodal support
 * Handles format conversion for different AI providers
 */
import { redactPathFromMessage } from "./logSanitize.js";
import type { ProcessedImage, FileProcessingResult } from "../types/index.js";
/**
 * Minimum bytes required just to detect an image format from magic bytes (#293).
 */
export declare const MIN_IMAGE_SIZE = 12;
/**
 * Minimum plausible byte size for a non-empty image of each format (#293). A
 * buffer that carries a format's magic bytes but is smaller than this is
 * truncated/corrupt and would fail (or render blank) downstream — reject early
 * with a clear message instead.
 *
 * Each threshold approximates the smallest byte count that format's
 * container can structurally be while still holding the mandatory
 * header/chunk skeleton for a minimal (e.g. 1×1 pixel) image — not an exact
 * spec minimum, but close enough that anything smaller is unambiguously
 * truncated:
 *  - **PNG (67)**: 8-byte signature + IHDR chunk (4 len + 4 type + 13 data +
 *    4 CRC = 25) + a minimal IDAT chunk carrying one zlib-compressed
 *    scanline (~22 bytes) + IEND chunk (4 len + 4 type + 0 data + 4 CRC =
 *    12) — matches the commonly-cited size of the smallest possible valid
 *    PNG (a 1×1 transparent pixel).
 *  - **JPEG (125)**: SOI + APP0/JFIF marker (18) + at least one DQT
 *    quantization table (~69 for one 8-bit luma table) + SOF0 + DHT + SOS
 *    headers + a minimal entropy-coded scan + EOI — the smallest legal
 *    baseline-JPEG skeleton for a 1×1 image.
 *  - **GIF (43)**: 6-byte GIF87a/89a header + 7-byte Logical Screen
 *    Descriptor + a 2-color (6-byte) color table + 10-byte Image
 *    Descriptor + minimal LZW-coded image sub-blocks + 1-byte trailer.
 *  - **WEBP (20)**: RIFF container header ("RIFF" + size + "WEBP" = 12
 *    bytes) + the first chunk's fourCC + size (8 bytes) — enough to confirm
 *    a well-formed RIFF/WEBP container and its first chunk, before any
 *    actual VP8/VP8L bitstream payload.
 *  - **AVIF (100)**: ISOBMFF `ftyp` box plus the mandatory `meta` box
 *    skeleton (`hdlr`/`pitm`/`iloc`/`iinf` sub-boxes) — roughly the minimum
 *    to hold AVIF's required box structure before any AV1 image item data.
 */
export declare const MIN_VALID_IMAGE_SIZE: Record<string, number>;
/**
 * Image processor class for handling provider-specific image formatting
 */
export declare class ImageProcessor {
    /**
     * Process image Buffer (unified interface)
     * Matches CSVProcessor.process() signature for consistency
     *
     * @param content - Image file as Buffer
     * @param options - Processing options (unused for now)
     * @returns Processed image as data URI
     */
    static process(content: Buffer, _options?: unknown): Promise<FileProcessingResult>;
    /**
     * Strict magic-byte match: does `content` actually begin with `mediaType`'s
     * signature? `detectImageType` returns `image/jpeg` as a *fallback* for
     * unrecognized data, so a per-format minimum must only be enforced when the
     * bytes genuinely match — otherwise valid BMP/TIFF/unknown buffers would be
     * wrongly rejected as "truncated jpeg" (#293 review).
     */
    private static hasStrictImageMagic;
    /**
     * Validate that a buffer is a plausibly-complete image (#293): non-empty and,
     * for a strictly-identified raster format, at least the minimum plausible byte
     * size. Returns the detected media type.
     *
     * @throws Error when the buffer is empty or a recognized format is truncated.
     */
    private static validateBufferNotEmpty;
    /**
     * Validate processed output meets required format
     * Checks:
     * - Base64 content is non-empty
     * - Data URI format is valid (data:{mimeType};base64,{content})
     * - MIME type is in the allowed list
     * @param dataUri - The complete data URI string
     * @param base64 - The base64-encoded content
     * @param mediaType - The MIME type of the image
     * @throws Error if any validation fails
     */
    private static validateProcessOutput;
    /**
     * Process image for OpenAI (requires data URI format)
     */
    static processImageForOpenAI(image: Buffer | string): string;
    /**
     * Process image for Google AI (requires base64 without data URI prefix)
     */
    static processImageForGoogle(image: Buffer | string): {
        mimeType: string;
        data: string;
    };
    /**
     * Process image for Anthropic (requires base64 without data URI prefix)
     */
    static processImageForAnthropic(image: Buffer | string): {
        mediaType: string;
        data: string;
    };
    /**
     * Process image for Vertex AI (model-specific routing)
     */
    static processImageForVertex(image: Buffer | string, model: string): {
        mimeType?: string;
        mediaType?: string;
        data: string;
    };
    /**
     * Detect image type from filename or data
     */
    static detectImageType(input: string | Buffer): string;
    /**
     * Throwing size guard for a raw byte length. Prevents memory exhaustion by
     * rejecting an oversized input BEFORE an unbounded read/allocation happens
     * (#257) — callers that can get a size cheaply (e.g. `fs.stat`) should
     * validate it before ever reading the bytes into memory. Default limit is
     * the canonical `SIZE_LIMITS_BYTES.IMAGE_MAX` (10 MB); there is no public
     * way to raise it — `maxSize` is an internal-only override for advanced
     * callers (e.g. video image inputs use a higher limit).
     *
     * @param size - Byte length to validate
     * @param context - Short label identifying the source (unused in the
     *   thrown message today, kept for call-site readability and future use)
     * @param maxSize - Max allowed size in bytes
     * @throws NeuroLinkError (`INVALID_IMAGE_SIZE`) if `size` is not a finite,
     *   non-negative number
     * @throws NeuroLinkError (`IMAGE_TOO_LARGE`) if `size` exceeds `maxSize`
     */
    static validateSize(size: number, context: string, maxSize?: number): void;
    /**
     * Throwing size guard for image buffers. Prevents memory exhaustion by
     * rejecting oversized buffers with a descriptive error BEFORE an unbounded
     * `Buffer.toString("base64")` allocation (#257). Delegates to
     * `validateSize` so buffer-based and pre-read (stat-based) callers share
     * one implementation.
     *
     * @param buffer - Image buffer to validate
     * @param context - Short label identifying the source (see `validateSize`)
     * @param maxSize - Max allowed size in bytes
     * @throws NeuroLinkError (`IMAGE_TOO_LARGE`) if the buffer exceeds `maxSize`
     */
    static validateBufferSize(buffer: Buffer, context: string, maxSize?: number): void;
    /**
     * Size-guarded Buffer → base64. Use in place of `buffer.toString("base64")`
     * on any path that converts a caller-supplied image buffer (#257).
     */
    static safeBase64Convert(buffer: Buffer, context: string, maxSize?: number): string;
    /**
     * Validate image format
     */
    static validateImageFormat(mediaType: string): boolean;
    /**
     * Get image dimensions from Buffer (basic implementation)
     */
    static getImageDimensions(buffer: Buffer): {
        width: number;
        height: number;
    } | null;
    /**
     * Convert image to ProcessedImage format
     */
    static processImage(image: Buffer | string, provider: string, model?: string): ProcessedImage;
}
/**
 * Whitelist of valid image file extensions (lowercase, no dots).
 * Used to validate file extensions against a known set of image formats.
 */
export declare const VALID_IMAGE_EXTENSIONS: string[];
/**
 * Utility functions for image handling
 */
export declare const imageUtils: {
    /**
     * Check if a string is a valid data URI
     */
    isDataUri: (str: string) => boolean;
    /**
     * Check if a string is a valid URL
     */
    isUrl: (str: string) => boolean;
    /**
     * Check if a string is base64 encoded
     */
    isBase64: (str: string) => boolean;
    /**
     * Extract file extension from filename or URL.
     * Strips query strings and fragments before matching so that
     * "image.jpg?v=1" correctly returns "jpg".
     * Returns null if no extension is found or if the extension
     * contains non-alphanumeric characters.
     */
    getFileExtension: (filename: string) => string | null;
    /**
     * Validate that an extension is a recognised image format.
     * Case-insensitive; rejects extensions with special characters.
     */
    isValidImageExtension: (extension: string) => boolean;
    /**
     * Extract and validate image file extension from a filename or URL.
     * Returns null if the extension is missing or not a recognised image format.
     *
     * Security note: the last extension is used, so "malware.exe.jpg" returns
     * "jpg". Callers should apply additional checks (e.g. content inspection)
     * where double-extension attacks are a concern.
     */
    getValidatedImageExtension: (filename: string) => string | null;
    /**
     * Convert file size to human readable format
     */
    formatFileSize: (bytes: number) => string;
    /**
     * Convert Buffer to base64 string. Guarded by the same #257 size limit as
     * every other conversion site (default `SIZE_LIMITS_BYTES.IMAGE_MAX`);
     * pass `maxBytes` to override for a caller with a legitimate need for a
     * different ceiling rather than silently accepting an unbounded buffer.
     * `imageUtils`/`ImageProcessor` are internal-only — not re-exported from
     * `src/lib/index.ts` or the package's public `exports` map — so this
     * default does not change behavior for any external SDK consumer.
     */
    bufferToBase64: (buffer: Buffer, maxBytes?: number) => string;
    /**
     * Convert base64 string to Buffer
     */
    base64ToBuffer: (base64: string) => Buffer;
    /**
     * Redact `filePath` (both as given and its `path.resolve()`'d form) from
     * an error message. Exposed directly (not just used internally by
     * {@link fileToBase64DataUri}) so the resolved-path branch can be verified
     * by a deterministic unit test — real `fs` errors only ever embed the
     * literal path as passed, never a resolved variant, so that branch isn't
     * otherwise observable through the async file-reading API.
     */
    redactPathFromMessage: typeof redactPathFromMessage;
    /**
     * Convert file path to base64 data URI
     */
    fileToBase64DataUri: (filePath: string, maxBytes?: number) => Promise<string>;
    /**
     * Convert URL to base64 data URI by downloading the image.
     * Implements retry logic with exponential backoff for network errors.
     *
     * Retries are performed for:
     * - Network errors (ECONNRESET, ENOTFOUND, ECONNREFUSED, ETIMEDOUT, ERR_NETWORK, AbortError)
     * - Server errors (5xx status codes)
     * - Rate limiting (429 Too Many Requests)
     * - Request timeouts (408 Request Timeout)
     *
     * Retries are NOT performed for:
     * - Client errors (4xx status codes except 408, 429)
     * - Invalid content type
     * - Content size limit exceeded
     * - Unsupported protocol
     *
     * @param url - The URL of the image to download
     * @param options - Configuration options
     * @param options.timeoutMs - Timeout for each download attempt (default: 15000ms)
     * @param options.maxBytes - Maximum allowed file size (default: 10MB)
     * @param options.maxAttempts - Maximum number of total attempts including initial attempt (default: 3)
     * @returns Promise<string> - Base64 data URI of the downloaded image
     * Rate-limited to 10 downloads per second to prevent DoS
     * Uses LRU cache to avoid redundant downloads of the same URL
     */
    urlToBase64DataUri: (url: string, { timeoutMs, maxBytes, maxAttempts, }?: {
        timeoutMs?: number;
        maxBytes?: number;
        maxAttempts?: number;
    }) => Promise<string>;
    /**
     * Extract base64 data from data URI
     */
    extractBase64FromDataUri: (dataUri: string) => string;
    /**
     * Extract MIME type from data URI
     */
    extractMimeTypeFromDataUri: (dataUri: string) => string;
    /**
     * Create data URI from base64 and MIME type
     */
    createDataUri: (base64: string, mimeType?: string) => string;
    /**
     * Validate base64 string format
     * Validates format BEFORE buffer allocation to prevent memory exhaustion
     */
    isValidBase64: (str: string) => boolean;
    /**
     * Get base64 string size in bytes
     */
    getBase64Size: (base64: string) => number;
    /**
     * Compress base64 image by reducing quality (basic implementation)
     * Note: This is a placeholder - for production use, consider using sharp or similar
     */
    compressBase64: (base64: string, _quality?: number) => string;
};
