4public sealed class NdsImage : IDisposable, IAsyncDisposable
7 private readonly IImageDataSource _source;
9 private bool _disposed;
19 IImageDataSource source,
22 IReadOnlyList<NdsOverlay> arm9Overlays,
23 IReadOnlyList<NdsOverlay> arm7Overlays,
50 public long Length => _source.Length;
60 CancellationToken cancellationToken =
default)
61 => await NdsImageLoader.OpenPathAsync(path, options, cancellationToken).ConfigureAwait(
false);
68 public static NdsImage
Open(
70 bool leaveOpen =
false,
72 => NdsImageLoader.OpenStream(stream, leaveOpen, options);
82 bool leaveOpen =
false,
84 CancellationToken cancellationToken =
default)
85 => await NdsImageLoader.OpenStreamAsync(stream, leaveOpen, options, cancellationToken).ConfigureAwait(
false);
93 => NdsImageLoader.LoadMemory(data, options);
100 ObjectDisposedException.ThrowIf(_disposed,
this);
101 ValidateRegion(region,
Length);
102 return new ImageSliceStream(_source, region);
113 CancellationToken cancellationToken =
default)
115 ObjectDisposedException.ThrowIf(_disposed,
this);
116 ArgumentNullException.ThrowIfNull(destination);
117 if (!destination.CanWrite)
119 throw new ArgumentException(
"The image-region destination must be writable.", nameof(destination));
122 using Stream source =
OpenRead(region);
123 await source.CopyToAsync(destination, cancellationToken).ConfigureAwait(
false);
140 CancellationToken cancellationToken =
default)
142 ObjectDisposedException.ThrowIf(_disposed,
this);
143 ArgumentNullException.ThrowIfNull(destination);
144 ArgumentNullException.ThrowIfNull(context);
146 throw new InvalidOperationException(
"A DS-only image does not declare modcrypt areas.");
149 using Stream source =
OpenRead(region);
156 cancellationToken: cancellationToken).ConfigureAwait(
false);
167 CancellationToken cancellationToken =
default)
169 ObjectDisposedException.ThrowIf(_disposed,
this);
170 ArgumentException.ThrowIfNullOrWhiteSpace(destination);
172 .ExtractAsync(cancellationToken);
179 ObjectDisposedException.ThrowIf(_disposed,
this);
188 ObjectDisposedException.ThrowIf(_disposed,
this);
191 return NdsImageValidator.Validate(
this, options);
199 ObjectDisposedException.ThrowIf(_disposed,
this);
209 CancellationToken cancellationToken =
default)
211 ObjectDisposedException.ThrowIf(_disposed,
this);
212 ArgumentNullException.ThrowIfNull(other);
237 await _source.DisposeAsync().ConfigureAwait(
false);
244 private static void ValidateRegion(
NdsRegion region,
long imageLength)
246 if (region.Offset < 0 || region.Length < 0 || region.Offset > imageLength - region.Length)
248 throw new ArgumentOutOfRangeException(nameof(region),
"The region is outside the image.");
Represents a versioned menu icon, localized titles, and optional DSi animation.
Provides tree, path, and file-ID access to an image's NitroFS.
Compares hash-bearing manifests so tooling can distinguish content edits from identity and layout cha...
static async ValueTask< NdsImageDiff > CompareAsync(NdsImage left, NdsImage right, CancellationToken cancellationToken=default)
Captures and compares two live images without taking ownership of either source.
Collects explicit image changes and saves them without mutating the source.
Provides a stable, content-addressed description of one parsed image for CI artifacts,...
static ValueTask< NdsImageManifest > CaptureAsync(NdsImage image, CancellationToken cancellationToken=default)
Captures hashes and structured metadata from a live image without taking ownership of it.
long Length
Reports physical source bytes, which may exceed the header's used-ROM size because cartridges are cap...
ValueTask< NdsExtractionResult > ExtractAsync(string destination, NdsExtractionOptions? options=null, CancellationToken cancellationToken=default)
Safely exports selected image components to a directory.
NdsValidationResult Validate(NdsValidationOptions? options=null)
Validates checksums, component relationships, bounds, and optional DSi authentication fields.
NdsHeader Header
Preserves both typed DS/DSi fields and the raw bytes required for checksums and lossless edits.
async ValueTask TransformModcryptAreaAsync(NdsModcryptArea area, Stream destination, NdsModcryptContext context, CancellationToken cancellationToken=default)
Reads one declared DSi modcrypt area and writes its symmetric AES-CTR transformation without loading ...
IReadOnlyList< NdsOverlay > Arm9Overlays
Gets ARM9 overlays in table order.
ValueTask< NdsImageManifest > CreateManifestAsync(CancellationToken cancellationToken=default)
Captures a detached, SHA-256-addressed automation manifest without transferring image ownership.
static NdsImage Open(Stream stream, bool leaveOpen=false, NdsReadOptions? options=null)
Opens an image from a caller-supplied readable, seekable stream.
Stream OpenRead(NdsRegion region)
Opens a read-only stream over a validated image region.
NdsFileSystem FileSystem
Connects navigable FNT paths with every FAT allocation, including unnamed overlay payloads.
NdsImageEditor Edit()
Begins an explicit, non-mutating edit session for this source image.
async ValueTask CopyToAsync(NdsRegion region, Stream destination, CancellationToken cancellationToken=default)
Copies an arbitrary validated image interval without materializing it as one managed array.
void Dispose()
Synchronously releases the image source and prevents further payload access.
static async ValueTask< NdsImage > OpenAsync(Stream stream, bool leaveOpen=false, NdsReadOptions? options=null, CancellationToken cancellationToken=default)
Asynchronously opens an image from a caller-supplied readable, seekable stream.
ValueTask< NdsImageDiff > CompareAsync(NdsImage other, CancellationToken cancellationToken=default)
Compares this image with another live image at semantic, numeric-identity, and physical-layout levels...
async ValueTask DisposeAsync()
Asynchronously releases the image source and prevents further payload access.
static async ValueTask< NdsImage > OpenAsync(string path, NdsReadOptions? options=null, CancellationToken cancellationToken=default)
Opens an image from a filesystem path without loading the entire file into memory.
IReadOnlyList< NdsOverlay > Arm7Overlays
Gets ARM7 overlays in table order.
static NdsImage Load(ReadOnlyMemory< byte > data, NdsReadOptions? options=null)
Loads an image from caller-owned memory.
NdsBanner? Banner
Gets the parsed menu banner, or null when absent.
Captures the AES-128 normal key and both HMAC-derived initial counters needed to transform DSi modcry...
Applies the DSi AES-CTR transform with little-endian counter advancement. Encryption and decryption a...
static async ValueTask TransformAsync(Stream source, Stream destination, long length, NdsModcryptContext context, NdsModcryptArea area, long byteOffset=0, CancellationToken cancellationToken=default)
Transforms exactly length bytes without closing either stream. If a late source truncation occurs,...
Controls resource limits applied while parsing an image.
Identifies a bounded range of bytes in an image.
Supplies optional trust material and policy for validation checks that cannot be inferred from image ...
static NdsValidationOptions Default
Returns a fresh keyless policy suitable for structural validation without shared mutable state.
Contains all diagnostics produced by a validation pass.
NdsModcryptArea
Identifies which DSi modcrypt interval and HMAC-derived initial counter a transformation uses.