UNPKG

ai-pp3

Version:

CLI tool combining multimodal AI analysis with RawTherapee's engine to generate optimized PP3 profiles for RAW photography

118 lines 3.94 kB
import { execa } from "execa"; import os from "node:os"; import path from "node:path"; import fs from "node:fs"; /** * Convert a DNG file to JPEG with specified quality and subsampling settings. * @param input Path to input DNG file * @param output Path to output JPEG file * @param quality JPEG quality (0-100) * @param subsampling JPEG chroma subsampling (1-3) */ export async function convertDngToImage({ input, output, quality = 90, subsampling = 3, format = "tiff", tiffCompression, bitDepth = 16, }) { validateQualityAndSubsampling(quality, subsampling); await validateOutputDirectory(output); const cliArguments = buildCliArguments({ output, format, quality, subsampling, tiffCompression, bitDepth, pp3Path: undefined, input, }); try { await execa("rawtherapee-cli", cliArguments); } catch (error) { throw new Error(`Conversion failed: ${error instanceof Error ? error.message : "Unknown error"}`); } } /** * Convert a DNG file to JPEG using a PP3 profile. * Always uses maximum quality settings for profile-based conversion. * @param input Path to input DNG file * @param output Path to output JPEG file * @param pp3Path Path to PP3 profile */ export async function convertDngToImageWithPP3({ input, output, pp3Path, quality = 100, subsampling = 3, format = "tiff", tiffCompression, bitDepth = 16, }) { if (!pp3Path) { throw new Error("PP3 profile path is required"); } validateQualityAndSubsampling(quality, subsampling); await validateOutputDirectory(output); const cliArguments = buildCliArguments({ output, format, quality, subsampling, tiffCompression, bitDepth, pp3Path, input, }); try { await execa("rawtherapee-cli", cliArguments); } catch (error) { throw new Error(`Conversion failed: ${error instanceof Error ? error.message : "Unknown error"}`); } } function validateQualityAndSubsampling(quality, subsampling) { if (quality < 0 || quality > 100) { throw new Error("Quality must be between 0 and 100"); } if (subsampling < 1 || subsampling > 3) { throw new Error("Subsampling must be between 1 and 3"); } } async function validateOutputDirectory(output) { const outputDirectory = path.dirname(output); try { await fs.promises.access(outputDirectory, fs.constants.W_OK); } catch (error) { if (error instanceof Error && "code" in error) { if (error.code === "ENOENT") { throw new Error(`Output directory does not exist: ${outputDirectory}`); } else if (error.code === "EACCES") { throw new Error(`Permission denied writing to output directory: ${outputDirectory}`); } } throw new Error(`Error accessing output directory: ${outputDirectory}`); } } function buildCliArguments({ output, format, quality, subsampling, tiffCompression, bitDepth, pp3Path, input, }) { const cliArguments = [ ...(os.platform() === "win32" ? ["-w"] : []), "-Y", pp3Path ? "-o" : "-O", output, ]; switch (format) { case "jpeg": { cliArguments.push(`-j${quality.toString()}`, `-js${subsampling.toString()}`); break; } case "tiff": { cliArguments.push("-t"); if (tiffCompression === "z") cliArguments.push("z"); break; } case "png": { cliArguments.push("-n"); break; } } if (pp3Path) { cliArguments.push(`-b${bitDepth.toString()}`, "-p", pp3Path, "-c", input); } else { cliArguments.push(`-b${bitDepth.toString()}`, "-c", input); } return cliArguments; } //# sourceMappingURL=raw-therapee-wrap.js.map