순차 for-loop(멀티코어를 1코어만 사용)을 코어 수 병렬로 — 50장 배치가 코어 수만큼 가속. ConvertOptions 불변(P4)이라 공유 읽기 스레드 안전. 시그니처 불변(내부 교체). - ConversionEngine.ConvertManyAsync: Independent 분기를 Parallel.ForEachAsync(MaxDOP=BatchParallelism)로. 결과는 인덱스 고정 ConvertResult[]로 순서 보존. 진행률은 완료 건수(Interlocked.Increment)로 보고 (파일별 분수 진행률은 동시 실행에서 의미가 흐려짐). DOP<=1이면 기존 순차 경로(세부 진행률 보존). CombineToSingle은 단일 연산이라 병렬 대상 아님(기존대로). - ConvertOptions.BatchParallelism(기본 = 논리 코어 수) 추가 — 미디어 위주 배치는 낮춰 튜닝 가능. - MagickProvider 정적 생성자: ResourceLimits.LimitMemory(60%) — 병렬 시 동시 MagickImage OOM 방지 (초과분 디스크 스필, 출력 바이트 무영향). - 신규 테스트: 8장 병렬 배치의 순서 보존(results[i]↔sources[i]) + 전수 변환 검증. 71개 테스트 전부 그린(골든마스터 동일성 유지), 빌드 0경고/0오류. ⚠ 진행률 UX(완료 건수 모델) 변경 — GUI 스모크 권장.
174 lines
5.2 KiB
C#
174 lines
5.2 KiB
C#
namespace Everything2Everything.Core;
|
|
|
|
public enum OutputLocation
|
|
{
|
|
SubfolderBesideSource,
|
|
SameFolderAsSource,
|
|
Custom
|
|
}
|
|
|
|
public enum NameCollision
|
|
{
|
|
AppendNumber,
|
|
Overwrite,
|
|
Skip
|
|
}
|
|
|
|
/// <summary>
|
|
/// 변환 옵션. 불변(record + init-only) — 구성된 뒤에는 변경되지 않으므로 배치 병렬 변환에서 안전하게 공유된다.
|
|
/// 변경이 필요하면 with 식으로 새 인스턴스를 만든다. (P4: mutable God Object → immutable record)
|
|
/// </summary>
|
|
public sealed record ConvertOptions
|
|
{
|
|
public OutputLocation OutputLocation { get; init; } = OutputLocation.SubfolderBesideSource;
|
|
|
|
public string SubfolderSuffix { get; init; } = "_converted";
|
|
|
|
public string? CustomOutputDirectory { get; init; }
|
|
|
|
public NameCollision OnCollision { get; init; } = NameCollision.AppendNumber;
|
|
|
|
public int? MaxLongEdgePixels { get; init; }
|
|
|
|
public bool KeepExifWhenPossible { get; init; } = true;
|
|
|
|
public bool FlattenTransparency { get; init; } = false;
|
|
|
|
public string TransparencyBackground { get; init; } = "#FFFFFF";
|
|
|
|
public JpegEncodingOptions Jpeg { get; init; } = new();
|
|
|
|
public PngEncodingOptions Png { get; init; } = new();
|
|
|
|
public WebpEncodingOptions Webp { get; init; } = new();
|
|
|
|
public AvifEncodingOptions Avif { get; init; } = new();
|
|
|
|
public TiffEncodingOptions Tiff { get; init; } = new();
|
|
|
|
public BmpEncodingOptions Bmp { get; init; } = new();
|
|
|
|
public GifEncodingOptions Gif { get; init; } = new();
|
|
|
|
public PdfRenderOptions PdfRender { get; init; } = new();
|
|
|
|
public PdfBuildOptions PdfBuild { get; init; } = new();
|
|
|
|
public HtmlRenderOptions HtmlRender { get; init; } = new();
|
|
|
|
public OcrOptions Ocr { get; init; } = new();
|
|
|
|
// --- 변환 그래프 경로 옵션 (P1) ---
|
|
/// <summary>멀티홉 경로 자동 합성 허용. false면 직접(1홉) 변환만.</summary>
|
|
public bool AllowMultiHop { get; init; } = true;
|
|
|
|
/// <summary>멀티홉 최대 홉 수.</summary>
|
|
public int MaxHops { get; init; } = 3;
|
|
|
|
/// <summary>래스터화 같은 큰 손실 엣지를 회피한다.</summary>
|
|
public bool AvoidLossy { get; init; } = false;
|
|
|
|
/// <summary>독립(Independent) 배치 변환의 최대 병렬 수. 기본 = 논리 코어 수. 미디어(FFmpeg) 위주 배치는 낮춰 오버서브스크립션 회피.</summary>
|
|
public int BatchParallelism { get; init; } = Environment.ProcessorCount;
|
|
|
|
/// <summary>영상 인코딩 시 GPU 하드웨어 가속(NVENC)을 우선 시도하고, 실패하면 CPU로 자동 폴백한다.</summary>
|
|
public bool VideoPreferGpu { get; init; } = true;
|
|
|
|
public PdfCompressOptions PdfCompress { get; init; } = new();
|
|
|
|
public AiOptions Ai { get; init; } = new();
|
|
|
|
public static ConvertOptions Quick() => new();
|
|
}
|
|
|
|
public sealed record JpegEncodingOptions
|
|
{
|
|
public int Quality { get; init; } = 92;
|
|
public bool Progressive { get; init; } = false;
|
|
}
|
|
|
|
public sealed record PngEncodingOptions
|
|
{
|
|
public int Compression { get; init; } = 7;
|
|
public bool Interlace { get; init; } = false;
|
|
}
|
|
|
|
public sealed record WebpEncodingOptions
|
|
{
|
|
public int Quality { get; init; } = 90;
|
|
public bool Lossless { get; init; } = false;
|
|
}
|
|
|
|
public sealed record AvifEncodingOptions
|
|
{
|
|
public int Quality { get; init; } = 60;
|
|
public int Speed { get; init; } = 6;
|
|
}
|
|
|
|
public sealed record TiffEncodingOptions
|
|
{
|
|
public string Compression { get; init; } = "lzw";
|
|
}
|
|
|
|
public sealed record BmpEncodingOptions
|
|
{
|
|
}
|
|
|
|
public sealed record GifEncodingOptions
|
|
{
|
|
}
|
|
|
|
public sealed record PdfRenderOptions
|
|
{
|
|
public int Dpi { get; init; } = 200;
|
|
public bool WithAnnotations { get; init; } = true;
|
|
public bool WithFormFill { get; init; } = true;
|
|
}
|
|
|
|
public sealed record PdfBuildOptions
|
|
{
|
|
public string PageSize { get; init; } = "Auto";
|
|
public int MarginPoints { get; init; } = 24;
|
|
public bool FitToPage { get; init; } = true;
|
|
}
|
|
|
|
public sealed record HtmlRenderOptions
|
|
{
|
|
public int ViewportWidth { get; init; } = 1280;
|
|
public int? ViewportHeight { get; init; }
|
|
public int WaitMilliseconds { get; init; } = 2000;
|
|
public bool FullPage { get; init; } = true;
|
|
}
|
|
|
|
public sealed record OcrOptions
|
|
{
|
|
public string Language { get; init; } = "ko+en";
|
|
public bool PreserveLayout { get; init; } = true;
|
|
public string Backend { get; init; } = "auto";
|
|
}
|
|
|
|
public sealed record PdfCompressOptions
|
|
{
|
|
/// <summary>Light(구조 최적화·무손실) | Strong(렌더 재인코딩) | Max(Ghostscript). P1은 Light만 구현.</summary>
|
|
public string Level { get; init; } = "Light";
|
|
}
|
|
|
|
public sealed record AiOptions
|
|
{
|
|
/// <summary>auto | openai | anthropic. auto는 설정된 키 중 가용한 것을 선택.</summary>
|
|
public string Backend { get; init; } = "auto";
|
|
|
|
/// <summary>모델 ID. null이면 백엔드별 기본값.</summary>
|
|
public string? Model { get; init; }
|
|
|
|
/// <summary>summarize | translate | proofread | custom.</summary>
|
|
public string Task { get; init; } = "summarize";
|
|
|
|
/// <summary>translate 작업의 대상 언어 (예: "영어", "일본어").</summary>
|
|
public string? TargetLanguage { get; init; }
|
|
|
|
/// <summary>custom 작업의 사용자 지정 지시문.</summary>
|
|
public string? Instruction { get; init; }
|
|
|
|
public int MaxOutputTokens { get; init; } = 2000;
|
|
}
|