+23
-9
@@ -6,9 +6,16 @@ Image Tools is a relocatable Vite/React application using the shared Toolbox she
|
||||
|
||||
Every selected `File` is untrusted. `src/image/headers.ts` reads a metadata window of at most the first 1 MiB with `Blob.slice()` and performs checked-offset parsing for JPEG markers, PNG chunks and WebP RIFF chunks. PNG and WebP receive an additional structural pass that reads only eight-byte chunk headers, skips payloads by checked offset, stops at image data, and refuses more than 4,096 pre-image chunks. This prevents APNG or animated-WebP control chunks hidden behind a large ancillary payload from bypassing static-only enforcement. Inspection establishes dimensions, recognized animation/multi-picture state, EXIF orientation and a bounded metadata inventory. The image is not given to a browser decoder until source, dimension, pixel and estimated-memory policies pass.
|
||||
|
||||
Each preview or export gets its own generation-bound module worker. The caller terminates the worker on replacement, cancellation, unmount or the 120-second deadline, so a stale result cannot replace current state. Files are structured-cloned to the worker; results return as `Blob` objects. Browsers without worker `OffscreenCanvas` use the same pure pipeline on the main thread and report missing capabilities instead of substituting a remote service.
|
||||
Each preview or export gets its own generation-bound module worker through the
|
||||
`@add-ideas/toolbox-helpers` worker-job protocol. The caller filters typed
|
||||
progress by job ID and terminates the worker on replacement, cancellation,
|
||||
unmount or the 120-second deadline, so a stale result cannot replace current
|
||||
state. Files are structured-cloned to the worker; results return as `Blob`
|
||||
objects. Browsers without worker `OffscreenCanvas` use the same pure pipeline
|
||||
on the main thread and report missing capabilities instead of substituting a
|
||||
remote service.
|
||||
|
||||
Object URLs are scoped to React lifecycles and revoked on replacement/unmount. Source files are never mutated. Downloads happen only after an explicit user action.
|
||||
Object URLs are scoped to React lifecycles and revoked on replacement/unmount. Source files are never mutated. Downloads happen only after an explicit user action. The crop overlay edits the same normalized rectangle consumed by the pipeline; zoom is view-only CSS state and never enters the recipe.
|
||||
|
||||
## Operation order
|
||||
|
||||
@@ -24,14 +31,21 @@ The canvas pipeline has one documented order:
|
||||
|
||||
The returned MIME type must exactly equal the requested type. A browser that substitutes PNG for an unsupported encoder produces an error and no misleading filename.
|
||||
|
||||
Intermediate canvases are released as soon as their next stage is drawn. The conservative preflight estimate allows twelve live bytes per source pixel, covers three RGBA-sized surfaces, and rejects sources above 40 megapixels or 512 MiB estimated working memory. Preview output is capped to a 1,600-pixel edge, while reports retain intended export dimensions. Batch execution is sequential and keeps at most 256 MiB of completed output blobs.
|
||||
Intermediate canvases are released as soon as their next stage is drawn. The conservative preflight estimate allows twelve live bytes per source pixel, covers three RGBA-sized surfaces, and rejects sources above 40 megapixels or 512 MiB estimated working memory. Preview output is capped to a 1,600-pixel edge, while reports retain intended export dimensions. Batch execution is sequential and keeps at most 256 MiB of completed output blobs. A separate fflate ZIP step reads at most 128 MiB of those blobs, uses fixed entry dates/collision-free names, includes operation reports and a manifest, and refuses output beyond 160 MiB.
|
||||
|
||||
Recipe JSON has an explicit `de.add-ideas.image-tools.recipe.v1` identity. Import validates every normalized crop, rotation, resize and output field before replacing state; unknown output formats cannot enter the processing pipeline through a recipe.
|
||||
|
||||
## Domain boundaries
|
||||
|
||||
Format inspection, checked limits, geometry, filenames, reports, downloads and processor RPC are separate modules under `src/image/`. These are deliberately shaped for later replacement with `@add-ideas/toolbox-helpers` primitives. The Helpers 0.1 package was not yet published while this slice was implemented, so Image Tools does not carry an unresolved dependency.
|
||||
Format inspection, checked image limits, geometry, filenames and reports remain
|
||||
domain modules under `src/image/`. Generic byte-size display, filename safety,
|
||||
Blob URL leases, single downloads and disposable-worker lifecycle come
|
||||
from `@add-ideas/toolbox-helpers` 0.2.0.
|
||||
|
||||
No third-party codec or helper runtime dependency is added in v0.1. Native
|
||||
codecs avoid a large WASM/source-identity release burden, at the cost of
|
||||
explicitly documented browser-dependent encoding and colour-management
|
||||
behaviour. A future controlled codec adapter can implement the same processing
|
||||
request/result contract without changing the UI model.
|
||||
No third-party image codec is added. The exactly pinned MIT-licensed `fflate`
|
||||
dependency writes the optional batch container only; it never decodes image
|
||||
pixels. Native codecs avoid a large
|
||||
WASM/source-identity release burden, at the cost of explicitly documented
|
||||
browser-dependent encoding and colour-management behaviour. A future
|
||||
controlled codec adapter can implement the same processing request/result
|
||||
contract without changing the UI model.
|
||||
|
||||
Reference in New Issue
Block a user