Skip to content

Releases: a-r-d/PureJsImage

PureJsImage v0.17.0

Choose a tag to compare

@a-r-d a-r-d released this 24 Aug 22:33

Added

  • Added an explicit optional Rust/WASM WebP accelerator with scalar and SIMD modules for VP8 row
    color conversion, VP8L predictor and color transforms, lossless encode transforms, and lossy
    RGBA or gray to YUV420 conversion. Measured RGB input keeps the existing paired-row TypeScript
    conversion because it is faster end to end. The TypeScript codec still owns RIFF parsing, entropy
    coding, limits, metadata, and bounded row orchestration. Module or kernel failures fall back to
    the TypeScript path. The pull-request corpus workflow now forces scalar and SIMD WebP runs and
    checks exact decode pixels, deterministic encode bytes, and actual kernel use.
  • Added a pull-request-only Imazen corpus workflow for JPEG, PNG, WebP, TIFF, GIF, and BMP. The
    workflow checks out the corpus at a pinned commit, runs every file in an isolated process, fails
    on per-file behavior changes, and uploads the generated reports for review.
  • Added forced scalar and SIMD Imazen lanes for JPEG, PNG, and WebP. Eligible inputs must execute
    the selected WASM kernels. JPEG and PNG decode pixels remain exact, deterministic scalar and PNG
    encoders require byte parity, and the SIMD JPEG AAN encoder keeps its existing PSNR and size gate.

Changed

  • Refreshed the stable-codec, cross-library web-codec, JPEG, PNG, and WebP WASM benchmarks, package
    metrics, result index, README charts, website charts, and accelerator benchmark pages after the
    current codec and runtime work.
  • Node orientation and rotation now use lazy chunked memory by default. Pass
    { temporaryFiles: true } as the second argument to createImageLibrary() to opt into a lower
    process-RSS file spool. The opt-in path probes file creation, writing, reading, and truncation
    before consuming image rows. Failed setup or later file writes fall back to memory. The previous
    64 MiB Node memory fallback ceiling has been removed; normal image limits still apply.
  • The optional WebP WASM accelerator now uses four-pixel SIMD for VP8L color transforms, fuses the
    common inverse color, predictor, and subtract-green row sequence into one call, and specializes
    uniform mode-11 prediction. Seven paired 4000x3000 lossless WebP trials reduced the median from
    617.90 ms to 518.50 ms, with exact output and a 2.00% peak RSS reduction.
  • The optional Rust/WASM JPEG encoder now uses a separable f32 AAN transform, precomputed
    reciprocal quantization factors, and four-pixel SIMD RGB and RGBA compositing and color
    conversion. Unused SIMD scratch arrays were removed. Seven paired end-to-end trials reduced the
    png-to-jpeg workflow median by 24.58% with the output quality, size, and correctness gates
    unchanged.
  • The optional Rust/WASM JPEG decoder now skips the full IDCT for DC-only blocks. Seven paired
    end-to-end trials reduced the jpeg-to-png workflow median by 5.64% with exact output
    correctness and a 0.46% peak RSS reduction.
  • JPEG WASM exactness now covers DC-only inverse-transform half-integer boundaries and scalar
    encoder values immediately below a positive half-integer. The Rust decoder now validates the
    end-of-scan marker after its final MCU while still allowing legal bytes after EOI.
  • Rust/WASM JPEG and PNG builds now reserve a bounded 128 KiB stack, trap on unexpected panics,
    and reject out-of-bounds or overlapping JPEG buffers before reading or writing memory. Initial
    accelerator memory remains within four WebAssembly pages.
  • The Imazen corpus command now accepts --baseline <directory> and exits with an error when a
    file changes outcome, completed stage, structured error, diagnostic, child exit code, or signal.
    Timing and machine metadata remain outside the comparison.

PureJsImage v0.16.0

Choose a tag to compare

@a-r-d a-r-d released this 22 Aug 02:26

Added

  • Added the purejsimage/geo raster API with CRS and affine grid metadata, resolution levels,
    bands and non-spatial axes, bounded pixel and world views, target-grid comparison, caller-supplied
    coordinate transforms, inverse-mapped reprojection, and the existing band math, terrain,
    statistics, histogram, and line-profile operations.
  • Added lazy geo readers for GeoTIFF and COG, GeoZarr v2 and v3, world-file TIFF, JPEG, and PNG,
    georeferenced ENVI, Esri ASCII Grid, SRTM HGT, and classic NetCDF CDF-1 and CDF-2 files with
    regular rectilinear CF coordinates. The readers preserve native sample values, selected
    multidimensional axes, cancellation, source ownership, and bounded region access where the
    source format permits it.
  • Added a generated geo compatibility manifest and deterministic CI benchmarks for remote COG,
    sharded and multidimensional GeoZarr, ENVI, classic NetCDF, and identity reprojection. The
    benchmark records request, byte, cache, chunk, shard, pixel, timing, and memory evidence while
    enforcing selective reads and output correctness.
  • Added the /geo/ browser demo with deterministic local fixtures, public Kentucky aerial imagery,
    a USGS Grand Canyon elevation COG, pan and zoom controls, hillshade, live range telemetry, clear
    loading and error states, and copyable examples for the active GeoTIFF or GeoZarr view.

Changed

  • The installed-package Geo consumer now runs deterministic range-backed GeoTIFF and
    multidimensional GeoZarr workflows through the public Geo, scientific, and tile-runtime entries.
    It also checks stable resource identity, cancellation ownership, exact cleanup, reprojection, and
    a browser Worker bundle. The Geo architecture guide now documents this application pattern.
  • GeoTIFF overview levels now derive their affine transform when an overview repeats CRS metadata
    without its own model transform. Hillshade reads its required one-pixel source border without
    weakening the 196,608-pixel output limit, and geo views preserve exact nodata values and source
    level identity. Geo reprojection policies, serialized plans, and result provenance now preserve
    caller-supplied full-range int64 and uint64 nodata as canonical decimal strings.

PureJsImage v0.14.0

Choose a tag to compare

@a-r-d a-r-d released this 20 Aug 04:11

PureJsImage 0.14.0 adds deterministic, bounded numeric-raster analysis plans and tile executors for band math, normalized difference, linear combinations, subtraction, terrain slope/aspect/hillshade, regional statistics and histograms, line profiles, explicit target-grid resampling, and caller-supplied inverse reprojection.

Plans record raw/scaled value handling, units, nodata, algorithm versions, coordinate-transform identity and accuracy, and explicit tile and memory limits without adding runtime dependencies or full-raster materialization.

The browser convert demo also keeps original and converted images side by side on large screens and includes constrained AVIF output.

PureJsImage v0.12.0

Choose a tag to compare

@a-r-d a-r-d released this 19 Aug 00:29

PureJsImage 0.12.0

Added

  • Added a deterministic Cloud Optimized GeoTIFF compatibility corpus, checked compression matrix,
    public bounded inspectCog() structural report, explicit compression ID/name errors, and a
    simulated-HTTP-range viewport benchmark that asserts overview selection and reports requests,
    bytes fetched, cache hits, first decoded tile-block latency, and decoded pixels.

  • Added typed GeoTIFF spatial references to ordinary TIFF scientific dataset descriptors and
    SubIFD levels, including CRS authority/code and citation, six-parameter pixel-to-model affine,
    invertible inverse, model bounds, pixel-is-area/point semantics, scalar or component GDAL nodata,
    and JSON-safe source metadata. Region reads remain in raster pixel coordinates, and malformed
    optional georeferencing does not block native TIFF pixels.

  • Expanded the official common-web (web-codecs) suite with JPEG→AVIF, JPEG→lossy WebP, AVIF
    crop+resize, the Lambda JPEG thumbnail, progressive JPEG resize, and lossless WebP alpha decode.
    The published speed and memory SVG charts include those jobs, and the README now shows both
    charts.

  • Added the explicit purejsimage/scientific/readers/ome-zarr reader for OME-NGFF 0.4 and 0.5
    image multiscales on first-party Zarr v2 and v3 directory stores. Selected planes fetch only
    intersecting regular or sharding_indexed chunks through the existing companion resolver; bytes,
    gzip, zlib, zstd, crc32c, transpose, shuffle, and Blosc 1 (LZ4/zlib/zstd/memcpy) are implemented;
    missing chunks become fill values. Sibling and root NGFF labels become separate datasets with
    image-label colors; plate wells become one dataset per field. A ZIP archive with root-level
    zarr.json or .zgroup opens as a single-file store without companions. Partial last chunks,
    sharded inner endian, Blosc split streams, and the C-Blosc compressor enumeration are handled.
    A pinned IDR 6001240 coarsest-plane slice cross-checks NGFF 0.4 Blosc/LZ4 against 0.5 sharded
    Blosc/zstd. The reader also accepts omitted v3 chunk_key_encoding, exact integer and hex
    fill_values, F-order padded last chunks, numeric OMERO colors, UTF-8 BOM metadata, and
    big-endian shard indexes, and rejects overlapping shard payloads. any-axis-pair planes are
    packed into destination row order. Zarr v2 fill_value: null decodes present chunks and fails
    on absent ones instead of inventing zeros; a present zero-byte chunk is malformed; missing
    shard inners use only the uint64 all-ones sentinel pair. Directory dataset identity includes
    defining metadata plus a session store id; ZIP identity stays the archive source. Chunk lookup
    uses a bounded LRU so maxOpenSources is not a lifetime visit limit. Clipped last chunks no
    longer fail when the nominal chunk exceeds the decode budget; empty optional .zattrs, trailing
    dataset slashes, bare one-byte NumPy dtypes, numcodecs.* codec ids, and case-insensitive
    NaN/Infinity fills are accepted. bioformats2raw 0/, 1/, … series roots and a single nested
    ZIP store prefix are supported; ambiguous multi-root ZIPs stay rejected. Series discovery also
    works without a root .zattrs file, bioformats2raw.layout may be a numeric string, and
    seriesCount counts series groups rather than every collected dataset. ZIP stores named
    *.zarr / *.ome.zarr probe as OME-Zarr, macOS __MACOSX/ sidecars no longer make a unique
    nested root look ambiguous, a root labels list does not hide bioformats2raw series, and extra
    integer series beyond maxDatasets raise LIMIT_EXCEEDED. ZIP probes use name-plus-magic
    evidence and do not open the archive. Generic Zarr v2 groups are not detected without NGFF
    attributes. Zarr storage fill is recorded as zarrFill rather than noDataValue; v3 rejects
    null and non-numeric integer fills; shard-index codecs must declare endian; nonempty
    storage_transformers are unsupported; NGFF axes must be time, then channel or custom, then
    2–3 spatial axes; OMERO colors must be six hex digits or 0–0xffffff; and the chunk cache is
    bounded by maxCachedChunkBytes. Pinned IDR slices now include 6001240 sibling labels, an
    IDR0010 0.5 plate well, an IDR0001 0.4 plate field, and an IDR0101 translation image. BloscLZ,
    Snappy, bitshuffle, tables, RFC-9 zip-comment/jsonFirst requirements, nonempty storage
    transformers, repeated transpose codecs, and writers remain explicit unsupported operations.
    ZIP members are limited before decompression; sharded plane reads resolve each shard once;
    bioformats2raw.layout must be 3; and directory calibration cites the resolved metadata
    resource id. Plane-session caches stay bounded and layer over the persistent chunk LRU;
    a source larger than maxCachedChunkBytes is held at most as one transient shard.

Changed

  • Speed up first-party AVIF decode after the retained inverse-transform skip: decode equiprobable
    bits without a throwaway CDF, skip zero-coefficient dequant, upsample interior 4:2:0 chroma
    without edge clips, renormalize the arithmetic coder with integer shifts, clamp YUV bytes with
    integer rounding, hoist SGR prefix-row bases, and inline the common 8-bit 4:2:0 convert. Local
    avif-fox-resize-jpeg fell from 589 ms to 500 ms (−15%) with an exact output hash; neighbor
    avif-fox-full-png improved 11%. The Imazen AVIF survey stayed 36/36 decoded with maximum RGB
    error 2; post-filter, color, high-bit, tile, q-matrix, and common-photo oracles were unchanged.
  • Speed up first-party AVIF inverse transforms by reusing residual scratch and skipping 1D
    transforms on all-zero rows and columns. Local avif-fox-resize-jpeg fell from 621 ms to 589 ms
    (−5%) with an exact output hash. The Imazen AVIF survey stayed 36/36 decoded with maximum RGB
    error 2; post-filter, high-bit, tile, q-matrix, and common-photo oracles were unchanged.
  • Speed up first-party AVIF loop restoration by specializing the 8-bit SGR box filter, restoring
    8-bit SGR/Wiener as unit-width tiles in 8-row bands, and applying interior Wiener 7-tap filters
    directly from the CDEF plane. Local avif-fox-resize-jpeg fell from 838 ms to 623 ms (−25%) with
    an exact output hash; neighbor avif-fox-full-png improved 18%. High-bit restoration stays on
    4-wide 4-row tiles so Int32 prefix squares do not overflow. The Imazen AVIF survey stayed 36/36
    decoded with maximum RGB error 2.
  • Fuse 8-bit AC Huffman prefix decoding into scaled JPEG block decode. Local jpeg-resize-1200
    fell from 543 ms to 511 ms (−7%) with an exact bitstream hash; neighbor jpeg-crop-resize
    improved 3.9% and northstar-photo-pipeline improved 3.4%. Imazen JPEG stayed 39 pass / 2
    unsupported / 167 rejected-safely / 46 accepted.
  • Speed up JPEG resize-to-encode pipelines by unrolling the scale-2 4×4 IDCT, skipping vertical
    chroma bilinear on 4:2:2 (chroma already has full vertical resolution), and unrolling the encoder
    DCT. Local jpeg-resize-1200 fell from 715 ms to 543 ms (−24%) with an exact bitstream hash;
    neighbor jpeg-crop-resize improved 18%. Imazen JPEG stayed 39 pass / 2 unsupported / 167
    rejected-safely / 46 accepted.
  • Speed up scaled JPEG decode by skipping unused AC store after the last zigzag the reduced IDCT
    reads, fusing leftover Huffman bit skips, unrolling the scale-4 2×2 IDCT, stopping restart
    indexing once the crop target is passed, and inlining leftover-AC skip on the entropy reader.
    Official northstar-photo-pipeline fell from 1181 ms to 802 ms (−32%) on top of the previous
    scaled-IDCT work, with an exact bitstream hash. Neighbor jpeg-crop-resize improved 13.5%;
    jpeg-resize-1200 kept its exact hash. Imazen JPEG stayed 39 pass / 2 unsupported / 167
    rejected-safely / 46 accepted.
  • Speed up large JPEG crop-then-resize pipelines by snapping unaligned decoder crops to a
    containing scale-aligned box so scaled IDCT can run. Official northstar-photo-pipeline fell
    from 2857 ms to 1181 ms (−59%). Pixel samples stayed inside the documented ±8 tolerance; the
    lossy JPEG bitstream changed as expected. Aligned neighbors kept exact hashes. Imazen JPEG
    stayed 39 pass / 2 unsupported / 167 rejected-safely / 46 accepted.
  • Speed up JPEG-to-PNG conversion by recycling decoder row buffers after encode, specializing
    adaptive PNG filter scoring for RGB8, and skipping bilinear luma interpolation when luma is
    already full resolution. Official jpeg-to-png fell from 552 ms to 444 ms (−20%) with a 6.5%
    peak-RSS drop on the recycle path; neighbor jpeg-resize-1200 improved 4.5%. Output hashes and
    the Imazen JPEG/PNG corpora were unchanged.
  • Fail full official web-codecs and competitors benchmark runs when any matched pass/pass wall
    median is more than 10% slower than the published headline snapshot. Single-workflow hillclimb
    runs are not gated.
  • Publish web-codec and competitor benchmark charts as SVG instead of rasterizing them to PNG.
  • Speed up first-party AVIF decode after the retained restoration gather/prefix work: hoist SGR
    prefixes, unroll Wiener and SGR blend, copy interior CDEF windows, reuse inverse-transform
    scratch buffers, specialize 4:2:0 chroma upsample, and specialize 8-bit Wiener rounding. Official
    avif-fox-resize-jpeg fell from 1452 ms to 803 ms (−45%) and avif-fox-full-png from 1573 ms to
    987 ms (−37%) on the 2026-08-17 web-codec snapshot, with unchanged output hashes.
  • Speed up first-party lossless WebP encoding by replacing the shifting LZ77 candidate table with a
    ring buffer, recording match tokens once for histogram and bitstream emission, and scoring color
    cache sizes in a single scan. Isolated 1200x480 effort-4 encode of transparent-logo-1200x480
    fell from 166 ms to 100 ms with an unchanged bitstream.
  • Speed up first-party lossy WebP encoding by adding the DC predictor during reconstruction instead
    of prefilling each 4x4, and by finalizing RGB8 chroma in the 2x2 write. Isolated 1200x900
    quality-80 enc...
Read more

PureJsImage v0.11.0

Choose a tag to compare

@a-r-d a-r-d released this 16 Aug 21:55

PureJsImage 0.11.0

Added

  • Added the explicit purejsimage/codecs/web entry with the frozen allWebCodecs JPEG, PNG, WebP,
    and AVIF aggregate, plus a correctness-gated common-web benchmark profile with AVIF metadata,
    full-decode, resize, conversion, and external Sharp and jSquash comparison rows. The historical
    ordinary competitor profile remains unchanged.

  • Completed the initial Milestone H interchange and detector set with explicit portable readers
    for RPL/RAW, EMSA/MAS, NRRD, MetaImage MHD/MHA, NIfTI-1/2 including bounded .nii.gz, NPY,
    NanoMegas BLO, processed Merlin MIB, and rectangular ANG/CTF orientation maps. The readers
    preserve native numeric samples and calibration evidence, provide bounded selected reads where
    their storage permits, reject recognized unsupported variants, ship as individual package
    entries, and pass generated structural, hostile-limit, packed-consumer, size, and real-Chromium
    coverage. Pinned RosettaSciIO files independently exercise RPL/RAW, ISO EMSA, BLO, and processed
    Merlin MIB without redistributing their GPL binaries. EDAX and Bruker BCF remain the roadmap's
    explicit later items.

  • Added the public purejsimage/scientific/readers/ncem-emd reader for the fixture-proven
    Berkeley/openNCEM 0.2 subset. It accepts integer or decimal-string versions, discovers numeric
    groups below /data or /signals, preserves exact labeled coordinates and bounded scalar or
    array acquisition metadata, and performs selected HDF5 hyperslab reads. Three pinned real
    RosettaSciIO application files join generated hostile and independent h5py coverage without
    redistributing their GPL binaries; Direct Electron .de5 remains explicitly unsupported.

  • Added the separate public purejsimage/scientific/readers/velox-emd E2 image reader with
    hierarchy-based probing, bounded per-frame JSON under an aggregate budget, separate detector
    datasets and frame axes, native scalar and complex data, preserved positive-half uncentered FFT
    storage, and explicit
    pruned-spectrum-image errors. Every metadata column is preserved, while calibration-critical
    conflicts fall back to index axes with a structured warning. Generated hostile fixtures and
    pinned TEM stack, DPC, and FFT files verify the reader without committing the GPL fixture
    binaries. Sparse Velox spectra remain gated on the Lab Viewer spectrum surface and explicit
    event-decoding contracts.

  • Added structured calibration provenance to scientific axes, including validated embedded,
    sidecar, derived, and format-default evidence. GSF, FITS, MRC/CCP4, OME-TIFF, and Aperio SVS
    readers now identify the exact source resource and stable metadata locator behind each available
    physical axis.

  • Added the public createImageCodecScientificReader() fallback adapter and individually
    importable PNG, JPEG, WebP, BMP, and JP2 scientific readers. They preserve codec pixels and
    component semantics, source identity, cancellation, block release ownership, and explicit reader
    registration without linking codecs into the base scientific entry.

  • Added purejsimage/scientific/readers/tiff, a native-precision ordinary TIFF reader with labeled
    page axes, incompatible-series separation, SubIFD resolution levels, bounded normalized optional
    metadata, native N-channel layouts, and lower probe priority than OME-TIFF and Aperio SVS.

  • Added bounded FEI SFEG/Helios and Zeiss SEM TIFF calibration profiles with fixture-backed physical
    axes, embedded evidence, normalized acquisition metadata, and non-fatal malformed-tag handling.

  • Added a package-private bounded DM3/DM4 tag-tree indexer with checked 32-bit and 64-bit structure,
    separate payload byte order, recursive value descriptors, deterministic duplicate-name paths,
    lazy image payload spans, and size-limited metadata projection for the upcoming scientific
    reader.

  • Added the public purejsimage/scientific/readers/digital-micrograph reader for supported DM3/DM4
    rank-2 through rank-4 scalar images and volumes, all signed/unsigned 8/16/32-bit and
    float32/float64 samples, fixture-proven packed BGRA, calibrated axes and intensity units,
    bounded namespaced Gatan metadata, and direct selected-region reads. Rank-1, complex,
    undocumented packed, encrypted, and external image content remains explicitly unsupported.

  • Added a generated scientific-reader capability section covering every public reader descriptor,
    package export, hint, resource model, dataset kind, direct-range boundary, evidence, and fixture
    source. Added a pinned, checksum-verified RosettaSciIO DigitalMicrograph compatibility corpus
    workflow without redistributing its GPL-licensed fixture binaries in the package repository.

  • Added evidence-gated DigitalMicrograph multidimensional semantics: ordinary X/Y/Z volumes,
    Gatan-tagged X/Y/energy EELS spectrum images, and C-ordered 4D-STEM exposed logically as
    scanX/scanY/kx/ky with direct kx/ky diffraction-plane reads. Ambiguous rank-4 arrays remain
    neutral. A pinned small DM4 volume and bounded HTTP-range verification of LiberTEM's 1.19 GB
    CC-BY-4.0 Zenodo 4D-STEM fixture cover the new mappings without committing the large file.

  • Added honest one-axis scientific datasets with explicit native series-read capabilities, bounded
    ScientificSeriesBlock output, strict series request normalization, and a bounded row/column
    adapter over existing plane readers. Existing plane-only descriptors and readers remain
    unchanged.

  • Added the public purejsimage/scientific/readers/tia-ser reader for FEI/Thermo TIA SER v528 and
    v544 scalar spectra, spectrum images, and image series. It indexes calibrated elements and valid
    counts without eager payload reads, preserves incomplete elements as bounded document metadata,
    provides direct canonical sample reads, and is verified against pinned real RosettaSciIO files
    without redistributing their GPL-licensed binaries.

  • Added the public purejsimage/scientific/readers/tia-emi companion reader for portable embedded
    ObjectInfo XML, numbered SER resource composition, acquisition metadata, stable identities,
    and evidence-preserving reciprocal-space reinterpretation. Contradictory SER coordinates remain
    authoritative and are reported rather than overwritten.

  • Added a package-private HDF5 file and address layer with legal user-block signature discovery,
    superblock versions 0 through 3, 2/4/8/16-byte integers, relocation-aware bigint addresses,
    lookup3 superblock checksum verification, and a bounded source-identity-aware metadata page
    cache. Legacy family, multi-file, and unknown drivers plus modern superblock extensions remain
    explicit unsupported boundaries while the object graph is implemented separately.

  • Added the first package-private HDF5 object-graph slice with version 1 and 2 object headers,
    checksummed continuation chunks, compact hard and soft links, link-info storage descriptors,
    bounded legacy symbol-table groups with local heaps and B-tree v1, and configurable
    hostile-metadata limits. A revision- and SHA-256-pinned HDF Group fixture verifies the real legacy
    group path without adding its binary to the repository.

  • Continued the package-private HDF5 object graph with checksummed fractal-heap headers, root direct
    and recursive indirect managed blocks, seven-byte managed heap IDs, and type-5 B-tree v2 leaf and
    internal nodes for modern dense groups. Generated hostile fixtures cover hard, soft, ASCII, UTF-8,
    creation-order, bounds, cycles, ordering, and corruption behavior. A second pinned HDF Group file
    verifies a real 40-record dense index and the explicit external-link boundary. Huge and tiny heap
    objects, filtered heaps, and the secondary creation-order index remain explicit deferred
    variants; bounded graph traversal, attributes, dataset layouts, chunk indexes, required filters,
    and exact selected reads are implemented by the later package-private D2-D6 layers. General
    public HDF5 reader claims remain intentionally absent.

  • Completed the fixture-proven package-private HDF5 D3-D6 substrate: bounded datatypes,
    dataspaces, attributes, compact/contiguous/chunked layouts, every required classic and modern
    chunk index, raw/Deflate/Shuffle/Fletcher32 filters, exact fill handling, local/HTTP parity, and
    cancellable selected dataset blocks. Contiguous rank-2 strided selections now batch many rows
    under independent input-span, output, and read-operation caps.

  • Added public Nanonis SXM, Igor Binary Wave v5, Digital Surf SUR/PRO, and ISO 5436-2 X3P surface
    readers plus a bounded ZIP/ZIP64 container. Committed test-only surface binaries now have a
    machine-readable per-file manifest with exact source revision/path/URL, license, attribution,
    redistribution rationale, SHA-256, and oracle.

Changed

  • Documentation pages keep wide tables, code samples, comparison matrices, and chip navigation
    inside named mobile scroll regions. The homepage comparison now leads with a compact six-dimension
    summary on narrow screens and keeps the full TIFF matrix in an expandable, prerendered section.
  • The README now leads with measured whole-slide, scientific explorer, and web codec memory visuals,
    and the generated scientific reader block is a family summary that links to the format reference.
  • Hardened scientific probing and metadata semantics after review: HDF5 dialect probes use exact
    eight-byte signature reads and pass the verified user-block offset into dialect opening; shared
    HDF5 loads isolate caller cancellation, preserve late-waiter coalescing, coalesce graph accounting,
    and cannot repopulate after close; Velox enforces its JSON budget across the complete document;
    NIfTI ignores scl_inter when scl_slope is zero, classifies affine columns relative to their
    own scale, and rejects non-finite header fields explicitly; and DM, TIA SER, Velox, and NIfTI
    omit physical units/evidence when numeric calibration is incomplete while re...
Read more

PureJsImage v0.9.0

Choose a tag to compare

@a-r-d a-r-d released this 10 Aug 23:06

Added

  • Expanded TIFF decoding with unsigned 6-, 10-, 12-, and 14-bit grayscale, 2-, 4-, 10-, 12-,
    and 14-bit chunky or planar RGB, native packed horizontal prediction, direct 16-bit output,
    and five-sample CMYK plus associated or unassociated alpha while retaining bounded segment
    memory.
  • Added explicit WebP-in-TIFF composition through
    createTiffCodec({ embeddedCodecs: [webpCodec] }); the default TIFF codec and root package do
    not import or activate WebP automatically.
  • Added a complete development-only TIFF dependency matrix plus isolated raw full-image and region
    benchmark operations with source-read, maximum decoded-block, external-memory, and ArrayBuffer
    measurements.
  • Added a generated evidence-backed TIFF library comparison across the README and documentation,
    backed by pinned versions and a 154-file isolated-process conformance run that reports exact
    pixels, mismatches, unsupported cases, errors, timeouts, crashes, native scientific rasters, and
    malformed-input behavior separately.
  • Expanded the browser demo from 8 to 38 public examples spanning ECCI scanning electron
    microscopy, OME-TIFF microscopy dimensions, FLIM, SPIM, high-content screening, pathology,
    scientific JPEG 2000, high-bit-depth AVIF, and additional unusual codec layouts.
  • Added a published llms.txt with a capability-manifest-generated codec map, complete quick API
    reference, runtime and safety boundaries, and migration guidance for Jimp, Sharp, image-js,
    jSquash, GeoTIFF.js, and UTIF.js; every website footer now links the guide and sitemap.
  • Added TIFF signed 8-/16-bit and IEEE float16/float32/float64 grayscale and RGB decoding with
    native-precision raw pixel blocks, deterministic display ranges, bounded Predictor 2 and
    floating Predictor 3 reversal, and browser-compatible display conversion.
  • Added unsigned 24-/32-/64-bit TIFF grayscale and RGB decoding with canonical gray32,
    rgb32, gray64, and rgb64 raw blocks, exact values above JavaScript's safe-integer range,
    bounded wide Predictor 2 reversal, and deterministic display conversion without an 8-/16-bit
    raw intermediate or per-pixel BigInt arithmetic.
  • Added bounded TIFF SGILog and SGILog24 decompression with native CIE Y/XYZ float32 pixel
    blocks, logarithmic luminance and chroma reconstruction, deterministic CCIR 709 gamma-2
    display conversion, exact segment validation, and browser-compatible strip and tile decoding.
  • Added explicit TIFF top-level frame and reduced-resolution SubIFD selection for Classic TIFF
    and BigTIFF, with selected-level metadata, bounded IFD graph traversal, cycle rejection,
    alias-safe shared-directory reuse, global directory limits, and no reads from unselected pixel
    segments.
  • Added 16-bit TIFF palette decode with exact full-range ColorMap scaling, plus signed 8-/16-bit
    and float16/float32/float64 CMYK display conversion using declared sample ranges or deterministic
    full-type defaults, bounded segment output, and independent pixel validation.
  • Added 8-bit TIFF CIELab conversion from D65-referenced Lab* to sRGB, bounded CMYK
    lut16 A2B0 ICC-profile conversion with profile precedence over numeric display, and
    FillOrder=2 normalization for non-fax strips and tiles before predictor reversal without
    mutating aliased source buffers.
  • Added a public TIFF document layer at purejsimage/tiff with stable top-level/SubIFD graphs,
    absolute IFD offsets and lookup, bounded defensive-copy private metadata reads, cached immutable
    typed tags with per-call limits, per-directory display and native raster decoders, deterministic
    third-party profile registration with isolated detector failures and ambiguity rejection, and
    typed explicit TiffProfile<T> opening.
  • Added native-precision planar or interleaved N-channel RasterBlock output plus explicit
    rasterToPixels() range mapping, so scientific samples no longer require an implicit RGB
    interpretation.
  • Added purejsimage/scientific OME-TIFF datasets with validated Z/C/T dimensions, channel and
    physical-pixel metadata, explicit or implicit TiffData plane mappings, separate-channel
    assembly, and reduced-resolution SubIFD selection.
  • Added a generic WholeSlideImage contract and first-party Aperio SVS profile with bounded
    pyramid/associated-image region reads, MPP and objective metadata, reusable JPEG 2000 codestream
    composition, and TIFF compression tags 33003/33005. The pinned irreversible Aperio tile is
    independently validated against OpenSlide within two 8-bit code values.
  • Added a separately compiled Leica SCN single-area profile example that imports only published
    package entries, with an automated boundary check suitable for independent vendor packages.
  • Added a dedicated TIFF documentation page covering the complete decode matrix, scientific and
    whole-slide APIs, third-party profiles, canonical output, memory model, and unsupported
    boundaries; reduced the README TIFF and Zstandard sections to direct documentation links and
    refreshed the measured bundle and installed-size tables.
  • Added a reusable first-party Zstandard decompressor at purejsimage/compression/zstd with
    explicit output and window bounds, raw/RLE/compressed blocks, Huffman and FSE entropy decoding,
    repeated tables and offsets, frame checksums, and structured malformed-input failures.
  • Added bounded TIFF Compression=50000 strip and tile decoding through the reusable Zstandard
    backend, preserving existing predictor, sample, and pixel processing.
  • Replaced simple uncompressed TIFF output with a canonical Classic little-endian 8-bit RGB/RGBA
    encoder using independently Deflate-compressed, horizontally predicted strips, automatic
    roughly 128 KiB strip planning, strict extensible strategy options, bounded raw strip scratch,
    compatible RGB ICC preservation, and exact ImageMagick/LibTIFF interoperability validation.
  • Added bounded first-party TIFF LERC2 and LERC-plus-Deflate segment decoding with mask handling,
    native numeric sample reconstruction, independently validated byte/float pixels, and structured
    rejection of corrupt headers, dimensions, masks, checksums, and codec metadata.
  • Added first-party GeoTIFF model, coordinate, bounding-box, GeoKey, GDAL metadata, and nodata
    helpers over the public TIFF document API, with exact affine and tiepoint semantics.
  • Added a bounded HttpRangeSource with request coalescing, validator-protected reads, byte-capped
    LRU caching, response cancellation, and selective COG-style region access that does not fetch
    unrelated tiles.
  • Expanded structured TIFF output with explicit rows per strip, tiled RGB/RGBA segments, automatic
    or explicit BigTIFF selection, multi-page top-level IFD chains, and reduced-resolution SubIFD
    pyramids, independently reopened through GeoTIFF.js.
  • Added a development-only TIFF conformance harness that scores PureJsImage, GeoTIFF.js, UTIF.js,
    image-js, and Jimp against independent sharp/ImageMagick RGBA output with isolated memory,
    timeout, crash, exact-pixel, and error reporting.

Changed

  • Moved OME-TIFF and raster helpers, Aperio SVS, and GeoTIFF profiles out of the root and browser
    entries into purejsimage/scientific, purejsimage/pathology, and purejsimage/tiff; moved
    HttpRangeSource into purejsimage/sources/http-range so the core bundle does not retain
    specialized TIFF workflows or the optional HTTP adapter.
  • Relabeled TIFF conformance as an unreleased commit-pinned workspace snapshot and made decoded
    coverage the compact comparison headline, with exact pixels and failure counts reported
    separately.

PureJsImage v0.8.0

Choose a tag to compare

@a-r-d a-r-d released this 10 Aug 03:13

Added

  • Extended the isolated Imazen codec-corpus harness and independent baselines across JPEG, PNG,
    WebP, TIFF, GIF, and BMP, covering complete decode-to-PNG round trips, structured rejection,
    timeouts, crashes, memory failures, upstream categories, and format-specific feature groups.
  • Added an explicitly imported first-party Rust/WASM PNG accelerator for common non-interlaced
    8-bit grayscale, RGB, and RGBA scanline decode and encode, retaining native runtime zlib,
    bounded-row memory, scalar fallback, and the TypeScript reference for every ineligible workload.
  • Added a separate purejsimage-wasm competitor benchmark engine and seven-engine speed, memory,
    and quality reports so the explicitly registered JPEG/PNG accelerators can be compared directly
    with the unchanged default TypeScript package.
  • Added an explicit optional first-party Rust/WASM baseline JPEG decoder that fuses entropy decode,
    IDCT, chroma upsampling, and RGB conversion while preserving bounded MCU-row output, exact
    TypeScript parity, lazy warm reuse, and clean fallback for unsupported or unhelpful workloads.
  • Added optional first-party scalar and SIMD Rust/WASM baseline JPEG encoders with bounded MCU-row
    input, JavaScript-owned sink backpressure, RGB/RGBA/grayscale and 4:2:0/4:2:2/4:4:4 parity, explicit
    workload selection, plus an ABI-compatible SIMD JPEG decoder artifact with scalar fallback.
    Specialized entropy writes, validated-row input reads, chroma sampling, Huffman lookup, and paired
    decoder upsampling reduce pinned warm encoder time by 61.7%-66.0% versus TypeScript and pinned warm
    decoder time by 58.4%, while retaining the same output contracts and bounded memory.
  • Added first-party refinement-based progressive JPEG encoding for grayscale and 4:2:0, 4:2:2,
    and 4:4:4 YCbCr output, with compact coefficient limits, per-scan restart markers, independent
    pixel validation, browser coverage, and isolated runtime/RSS/size benchmarks.
  • Added jSquash as an isolated WebAssembly competitor using its pinned JPEG, PNG, WebP, and resize
    packages, with documented Node WASM initialization, explicit unsupported classifications,
    startup/package-footprint measurements, a codec-matched bundle comparison with exact package
    versions, validated workflow results, and regenerated charts.
  • Added premultiplied-RGBA PSNR against independent exact-area references to quality-enabled
    competitor workflows, with quality recorded outside timing and peak-RSS sampling, included in
    Markdown and JSON reports, and published as a dedicated comparison chart.
  • Added a fully client-side browser conversion demo with content-based format detection, optional
    transforms, honest timing and memory reporting, and an artifact-only GitHub Pages deployment
    that keeps its generated all-codec bundle out of repository history.

Changed

  • Moved HEIF/HEIC decode to the explicit
    purejsimage/codecs/experimental/heic entry, removed it from allCodecs and
    the default browser demo, and documented that MIT grants no third-party HEVC
    patent rights.
  • Documented when native Sharp is the better performance choice and added measured Lambda sizing
    guidance: 256 MiB completed every pinned 12-megapixel workflow, but 1024 MiB cut the JPEG-to-WebP
    warm operation from 10.6 seconds to 2.5 seconds while peak use remained about 120 MiB.

Fixed

  • Kept the nested packed-declaration smoke test operational during npm pack --dry-run, so the
    documented release gate validates package contents instead of inheriting npm's outer dry-run mode.

  • JPEG decoding now treats sampling factors as one for single-component non-interleaved scans,
    tolerantly preserves completed progressive coefficients when a partial scan reaches a DHT, SOS,
    or EOI boundary, and decodes AVI1/MJPEG baseline frames that omit standard Huffman tables. Strict
    progressive decoding continues to reject partial entropy.

  • Recognized 12-bit and arithmetic-coded JPEG inputs now fail with UNSUPPORTED_OPERATION,
    separating deliberate codec boundaries from supported-subset failures in the Imazen conformance
    baseline.

  • TIFF decoding now defers BigTIFF offset validation until an inline value actually needs an
    external offset, recognizes legacy LSB-packed LZW streams with late code-width changes, accepts
    legacy tile tables in strip tags, bounds padded final YCbCr LZW strips, reconstructs multi-strip
    old-style JPEGs with omitted legacy fields, and decodes one-dimensional Group 3 fax rows without
    EOL markers. Recognized 64-bit sample layouts remain structured unsupported boundaries. BMP RLE4
    now accepts the single encoded padding pixel used for odd-width scanlines while retaining overrun
    rejection.

  • Animated GIF pixel decode now fails with UNSUPPORTED_OPERATION instead of silently discarding
    animation; callers can explicitly request the supported first image with open(input, { frame: 0 }).

  • Baseline JPEG restart recovery now defaults to tolerant decoding for malformed real-world files;
    pass open(input, { tolerantDecoding: false }) to require strict restart sequencing. Explicit
    Rust/WASM decoding now implements the same bounded recovery instead of being skipped. JPEG and
    PNG decode accelerator setup or midstream failures now resume through their TypeScript decoders
    without duplicate rows. Focused scalar and SIMD PNG regressions keep trailing IEND data,
    full-range cICP, and ICC v4 RGB mAB color conversion at parity without silently falling back.
    The same corpus-driven work completed those compatibility fixes for the TypeScript reference.

  • Removed ambient Buffer references from the Node entry's published declarations so strict
    TypeScript consumers can compile the zero-dependency package without installing @types/node.

  • Changed the default resize kernel from bilinear to scale-aware Lanczos 3 so ordinary downscales
    no longer discard most source samples and alias heavily; strong downscales now use bounded
    streaming box pre-shrink before the final Lanczos pass, format-specialized horizontal kernels,
    opaque-RGBA handling, and a fixed retained-row ring instead of a map. Bilinear remains available
    as an explicit faster, lower-quality option, and benchmark reports identify cross-kernel
    comparisons. On the pinned profiles, the 4× PNG resize fell from 1,253 ms to 530 ms and the
    10× 100-megapixel downscale fell from 8,455 ms to 2,408 ms.

  • Allowed the browser demo to convert the supported primary image from iPhone-style MPF JPEGs while
    warning that auxiliary images and gain maps are not preserved; true animated inputs remain blocked.

  • Reduced progressive JPEG output with two-pass, scan-specific optimized Huffman tables; the pinned
    quality-80 benchmark moved from 3.29% larger than baseline to 7.26% smaller with identical decoded
    PSNR.

  • Corrected AV1 quantization-matrix coefficient-axis lookup and adjusted matrix
    dimensions for 64-point transforms, with q30-q90 YUV and displayed-RGB gates
    against independent libaom, dav1d, Sharp, and Chromium decoders.

  • Reduced lossless WebP output for screenshot-style pixels with block-adaptive VP8L predictors,
    adaptive color-cache codes, and a deeper bounded match search, while retaining exact independent
    libwebp pixel validation and documenting the fixed match-table memory cost.

  • Fixed progressive JPEG AC refinement after a zero-run-length symbol so common Sharp/libjpeg
    output decodes correctly and can be resized and converted to WebP in Node.js and browsers.

PureJsImage v0.7.0

Choose a tag to compare

@a-r-d a-r-d released this 10 Aug 03:07

Added

  • Completed the common static 8-bit Huffman JPEG reference before optional WASM work: incremental
    entropy input, restart-aware region seeking, chroma-aware bilinear upsampling, SOF1 and sequential
    multi-scan decode, 4:4:0 and 4:1:1 fixtures, native grayscale and restart-marker output, hostile
    input limits, and provider-neutral parity vectors.
  • Added native 1/2, 1/4, and 1/8 JPEG IDCT output, decoder-driven scale selection for safe
    full-frame downscales, baseline/progressive/restart/subsampling regressions, and an isolated
    runtime, RSS, avoided-pixel, and output-error benchmark against the full-resolution path.
  • Added an explicit modern-browser entry with File/Blob, ArrayBuffer, Uint8Array, Blob output,
    custom sinks, browser-safe TypeScript declarations, and a browser bundle gate that rejects Node
    built-ins across the full codec graph.
  • Added browser PNG encoding through CompressionStream and bounded browser rotation/orientation
    storage through OPFS, a lazy 64 MiB chunked-memory fallback, and IndexedDB for larger transforms.
  • Added HEIF/HEIC EXIF and RGB ICC preservation for conversion workflows, including orientation
    normalization, plus structured ICC and nclx color-profile metadata for HEIF and AVIF.
  • Refreshed the static GitHub Pages documentation with responsive guides, API and codec references,
    benchmark tables, memory-model explanations, and clearer capability boundaries.
  • Documented the progressive JavaScript, optional WASM, and future WebGPU backend roadmap,
    including capability probing, workload-based selection, bounded GPU memory rules, runtime
    fallback policy, correctness gates, and a staged browser-first delivery plan.
  • Added a reproducible bundle and deployment-footprint comparison for PureJsImage, Jimp, image-js,
    and Sharp, with a matched common codec set and explicit accounting for Sharp's native payload.
  • Added one machine-readable codec capability manifest that generates README, detailed codec,
    website, public JSON, and compatibility-test expectations, with a stale-output CI gate and a
    repository agent skill for rolling capabilities out consistently.

Changed

  • Made bundle and installed-package size reporting part of the mandatory npm run check gate.
  • Reworked the root README into a shorter human-facing overview with a practical all-codec example,
    bundle sizes, codec support and compatibility links, benchmark charts, and direct routes to the
    API, benchmark, browser, temporary-storage, specification, and contributor details.
  • Split Node file, Buffer, zlib, and temporary-file services from the portable codec and pipeline
    core while preserving the existing Node API and measured transform performance.
  • Made Node.js and modern-browser portability an explicit project goal and release requirement.
  • Reused a single Node file descriptor across detection, metadata, and execution reads, and avoided
    redundant copies when stable sources fill codec regions.
  • Surfaced the measured 191.8-211.0 MiB JPEG 2000 decode peak and its 512 MiB Lambda-tier guidance
    in the README and codec documentation.

Fixed

  • Reduced first-party lossless WebP output for graphics by adding predictor and subtract-green
    transforms, LZ77 references, and adaptive Huffman trees, with exact Sharp/libwebp pixel checks
    and an isolated size and peak-memory benchmark for the documented full-frame encoder state.
  • Decoded the quantization matrices and block delta-Q syntax used by default Sharp/libaom AVIF
    output in the restricted opaque 8-bit YUV 4:2:0 path, with exact q50 and q80 YUV agreement
    against both dav1d and libaom while delta loop-filter syntax remains explicitly unsupported.
  • Restricted SVG recognition to the document's first element so HTML with inline SVG and JSON text
    mentioning <svg are no longer misreported as SVG input.

PureJsImage v0.6.0

Choose a tag to compare

@a-r-d a-r-d released this 08 Aug 16:56

Added

  • Added first-party JPEG 2000 / JP2 decoding for common Part 1 grayscale and RGB still images,
    including reversible 5/3 and irreversible 9/7 reconstruction, all five progression orders,
    multiple tiles, 1-16-bit unsigned samples, strict container validation, public pipeline
    conversion, and checksum-pinned fixtures from independent encoders.
  • Added public-domain real-photograph JP2 fixtures with exact OpenJPEG oracle hashes, structured
    container and codestream corruption regressions, a deterministic JP2 mutation campaign, decoded
    allocation-limit tests, and isolated cold/warm RSS gates for the documented full-frame fallback.
  • Added ordered, composable spatial stages: crop-after-resize, multiple resize stages, clockwise
    rotate() with arbitrary-angle bilinear sampling, vertical flip(), and horizontal flop().
  • Added opt-in keepExif() and keepIcc() pipeline operations with JPEG, PNG, and WebP metadata
    round trips, TIFF ICC round trips, orientation normalization after pixel reorientation, and
    explicit errors for unsupported preservation combinations.
  • Added a transform-to-JPEG benchmark profile covering quarter-turn and arbitrary rotation,
    crop-after-resize with a second resize, and combined flip/flop workflows, with isolated timing,
    peak RSS, dimensions, pinned output-pixel validation, and an equivalent-workflow Jimp comparison.
  • Added a cross-codec transform contract that runs the full ordered transform chain from every
    supported decoder through JPEG output, plus focused arbitrary-rotation coverage for grayscale,
    RGB, and RGBA sample formats.
  • Added a contributor guide covering tests, benchmarks, modular feature design, documentation,
    changelog entries, AI-assisted changes, MIT licensing, and conflict-free pull requests to main.
  • Added a repository release skill with explicit authority, validation, packaging, publishing,
    provenance, and post-release consistency gates.
  • Added a private vulnerability disclosure policy that defines the dependency-free runtime boundary
    while keeping CI, build, credential, and published-artifact supply-chain risks in scope.
  • Added weekly and change-triggered CodeQL analysis for JavaScript and TypeScript using the extended
    security query suite.
  • Added runtime validation for custom ImageSource reads, normalizing short, oversized, detached,
    and rejected reads into contextual ImageError results before codec parsing.
  • Added a release-gated deterministic corruption campaign with hundreds of bit flips across a
    committed benchmark seed for every codec, saved raw-exception reproducers, and a checked-in
    regression corpus that automatically turns promoted crashes into permanent tests.

Changed

  • Kept arbitrary-angle rotation memory bounded with a temporary 32x32 tile spool and small
    destination blocks, without per-pixel promises or temporary sample arrays.

PureJsImage v0.5.0

Choose a tag to compare

@a-r-d a-r-d released this 08 Aug 16:52

Added

  • Added first-party ICO decoding with validated multi-image selection,
    zero-copy embedded PNG entries, common 1/4/8/16/24/32-bit DIB layouts,
    one-bit AND masks, partial alpha, and the Windows-compatible legacy
    all-zero-alpha fallback.
  • Added a committed, checksum-pinned ICO corpus plus correctness-gated isolated
    benchmarks for metadata, embedded PNG and DIB decoding, masks, alpha, resize,
    PNG output, and JPEG output.
  • Expanded first-party TIFF decoding with BigTIFF 64-bit IFDs and offsets,
    padded tiled layouts, 16-bit integer channels, CMYK and subsampled YCbCr
    conversion, CCITT Modified Huffman and Group 3 fax, and old/new JPEG-in-TIFF.