Releases: bfactory-ai/zignal
zignal 0.8.0
Highlights
- New APIs: Rectangle helpers (centers/corners/clip/covers), byte-buffer image loading (Image.loadFromBytes / load_from_bytes), color-wide invert(), and mean pixel error metrics join PSNR/SSIM for easier quality checks.
- Linear Algebra Refresh: Matrix norms break out into explicit helpers (element, Schatten, induced, nuclear, spectral, etc.), with clearer error surfaces on invalid parameters.
- Visualization & Examples: Canvas line rendering gains smoother anti-aliased endpoints, and a new contrast-enhancement WASM demo shows off histogram/auto-contrast controls.
- Performance: Integral images now use a unified planar integral layout, speeding up multi-channel box blurs and simplifying the API.
- Stability Fixes: Safer transforms (rank/solver errors bubble out), ORB matcher memory handling, thick-line alpha blending, and hardened PCF/BDF font parsers.
What's Changed
- feat(geom): add rectangle accessors and utilities by @arrufat in #215
- fix(matrix): propagate errors in binary arithmetic ops by @arrufat in #217
- refactor(python): introduce utilities for getters and projections by @arrufat in #218
- feat(matrix): add schatten, induced, and element norms by @arrufat in #219
- feat(example): add contrast enhancement demo by @arrufat in #220
- fix(pcf): correct format flag decoding and add bounds checks by @arrufat in #221
- fix(bdf): parse glyph rows wider than 32 bits by @arrufat in #222
- feat(image): allow loading images from byte buffers by @arrufat in #223
- fix(geometry): return error if transform SVD fails by @arrufat in #224
- fix(features): ensure memory safety and handle orb scale edge cases by @arrufat in #225
- feat(canvas): improve line endpoint anti-aliasing by @arrufat in #226
- feat(color): implement generic color inversion by @arrufat in #227
- refactor(io): simplify image file loading by @arrufat in #228
- feat(metrics): add mean pixel error calculation by @arrufat in #229
- perf(image): use planar integral image for unified API by @arrufat in #230
Full Changelog: 0.7.1...0.8.0
zignal 0.7.1
Highlights
- Faster pipelines: Convolution now skips redundant work for uniform RGB channels and leverages SIMD kernels, while the sixel encoder received a full rewrite with smarter palette generation, chunking, and profiling hooks, dramatically cutting time-to-frame for terminal renders.
- Safer numerics: Matrix GEMM now correctly dispatches Aᵀ * Bᵀ paths to SIMD helpers, and JPEG/PNG decoders gained hardened restart-marker handling plus accurate 16‑bit channel extraction to stop stray color swaps.
- Better accuracy: Feature Distribution Matching honours grayscale targets again, rectangles perform more stable overlap checks, and canvas drawing floors fractional coordinates to eliminate off-by-one artefacts.
- Tidier internals: Image quality helpers (PSNR/SSIM) moved into image/metrics.zig, paving the way for new example (like the fresh metrics demo) while web samples were refreshed to showcase the improved terminal encoders.
Python Bindings
- Added zignal.RunningStats, mirroring Zig’s streaming statistics (mean, variance, skewness, etc.) with add, extend, combine, and scale helpers plus read-only properties.
- Exposed zignal.perlin(...), bringing the 3D Perlin noise generator to Python with guarded amplitude, frequency, octave, persistence and lacunarity controls.
- Tightened parameter validation across bindings (clear ValueErrors) and fixed pixel-proxy lifetime handling for long-running iterations.
What's Changed
- refactor: generalize binding operators and image conversion by @arrufat in #199
- refactor: improve ORB feature distribution and resource management by @arrufat in #200
- refactor(image): extract pixel assignment logic to standalone function by @arrufat in #201
- refactor(image): improve memory and data handling by @arrufat in #202
- perf(convolution): skip convolution for uniform channels by @arrufat in #203
- fix(python): manage pyobject references in iterator and proxy by @arrufat in #204
- refactor(python): use (N) format unit in Py_BuildValue by @arrufat in #205
- perf(sixel): optimize encoding and add profiling support by @arrufat in #206
- fix(jpeg): improve robustness and memory safety by @arrufat in #207
- fix(fdm): match color source against grayscale target by @arrufat in #208
- refactor(image): move metrics to their own module by @arrufat in #209
- fix(png): correct 16-bit pixel extraction offsets by @arrufat in #210
- fix(matrix): correctly handle A^T * B^T in SIMD GEMM by @arrufat in #211
- perf(convolution): simd + uniform channels by @arrufat in #212
- feat(python): expose running stats class by @arrufat in #213
- feat(python): expose perlin noise function in python bindings by @arrufat in #214
Full Changelog: 0.7.0...0.7.1
zignal 0.7.0
HIghlights
- SSIM scoring landed for Image.ssim, giving perceptual quality metrics directly in Zig and Python.
- Matrix module adds SVD-powered pseudoInverse, richer error reporting, and faster PCA projection via SIMD.
- Python Matrix bindings now behave like native numeric types, expose LU/QR/SVD/pinv, and ship new constructors plus 3.10 to 3.14 wheel support.
- Image filters now require preallocated outputs (Image.initLike/dupe); update callers, switch to Point.init, and replace meta.clampU8/clampTo with meta.clamp.
- Fixes include steady-state deflate reuse, stride-safe canvas drawing, NaN-resistant rectangles, and corrected edge copying.
What's Changed
- refactor(image)!: standardize output buffer handling by @arrufat in #192
- refactor(geometry): unify Point init and add vector utilities by @arrufat in #193
- feat(matrix): implement Moore-Penrose pseudoinverse by @arrufat in #194
- feat(image): implement structural similarity index (ssim) by @arrufat in #195
- docs(python): enhance README with badges and detailed features by @arrufat in #196
- feat(python): add matrix bindings by @arrufat in #197
- ci: add python 3.14 to test matrix by @arrufat in #198
Full Changelog: 0.6.0...0.7.0
zignal 0.6.0
Highlights
Edge Detection Algorithms
- Canny Edge Detector - Classic multi-stage algorithm with configurable Gaussian smoothing and dual thresholding (defaults: σ=1.4, low=50, high=150)
- Shen-Castan - Advanced edge detection using ISEF smoothing with adaptive gradient computation
Binary Image Operations
- Otsu and adaptive mean thresholding
- Morphological operations: erosion, dilation, opening, closing
Order-Statistic Filters
- Median, min, and max filters for edge-preserving blur
Image Enhancement
- Histogram equalization
- Automatic contrast adjustment
Additional Features
- Canvas draw_image() method for image compositing with blending
- JPEG output support via image.save()
What's Changed
- feat(python): add Shen-Castan edge detection by @arrufat in #168
- feat(image): add image invert method by @arrufat in #169
- refactor(enum): centralize Python enum registration by @arrufat in #170
- refactor(image): extract image to python object conversion by @arrufat in #171
- refactor: python binding utils by @arrufat in #172
- refactor: python arg parsing by @arrufat in #173
- refactor: introduce pycanvas and use parseArgs in canvas by @arrufat in #174
- feat(jpeg): add baseline JPEG encoder with optimized DCT by @arrufat in #175
- feat(image): allow saving images as jpeg by @arrufat in #176
- feat(image): add autocontrast function by @arrufat in #177
- feat(image): add histogram equalization by @arrufat in #178
- feat(python): expose difference of gaussians filter by @arrufat in #179
- refactor(python): standardize object lifecycle and error handling by @arrufat in #180
- refactor(build): improve wheel cleanup and add extension validation by @arrufat in #181
- test(python): standardize test naming and remove redundant docstrings by @arrufat in #182
- refactor(png): unify Adam7 deinterlacing logic for palette images by @arrufat in #183
- feat(canvas): add draw image method by @arrufat in #184
- feat(image): enable blending mode for image insertion by @arrufat in #185
- feat(image): add binary thresholding and morphology by @arrufat in #186
- feat(image): add order-statistic blur filters by @arrufat in #187
- refactor(python): standardize argument parsing by @arrufat in #189
- refactor(py): generalize python type object definitions by @arrufat in #190
- feat: add Canny edge detection algorithm by @arrufat in #191
Full Changelog: 0.5.1...0.6.0
zignal 0.5.1
What's Changed
- refactor: update to Io.Reader/Io.Writer by @arrufat in #167
- fix:
Image.__format__was lost in a refactor, added it back again, sorry! - updated minimum zig version to: 0.16.0-dev.164+bc7955306
Full Changelog: 0.5.0...0.5.1
zignal 0.5.0
A major release bringing computer vision capabilities, advanced filtering, and significant Python API improvements.
Highlights
Computer Vision
- ORB feature detection with FAST corners and binary descriptors
- Multi-scale image pyramids
Optimization
- Hungarian algorithm for optimal assignment problems
Image Processing
- Convolution framework with Gaussian blur, DoG, and Sobel filters
- Motion blur effects (linear and radial) with SIMD optimization
- 12 blend modes for advanced compositing
- Image transforms: rotation, warping, perspective
- PSNR quality metrics
Python Enhancements
- Matrix class with NumPy interoperability
- PCA (Principal Component Analysis) implementation
- Direct pixel access: image[y,x].r = 255
- Improved NumPy integration with strided arrays
- Arc drawing and enhanced Canvas API
- Modern type hints with comprehensive stubs
Architecture
- Refactored image module into logical sub-modules
- Dynamic SVD for runtime dimensions
- Enhanced font system with full Unicode support
- SIMD optimizations throughout
Breaking Changes
- Enum renames: InterpolationMethod → Interpolation, BlendMode → Blending
- Rectangle bounds now exclusive (was inclusive)
- Python: Canvas.draw_text parameter order changed
- Image constructor renames for clarity
Performance
- 2-5x speedup in filtering operations via SIMD
- Optimized integral images and convolution
- Channel-separated processing for better cache locality
What's Changed
- feat(image): add image rotation with interpolation by @arrufat in #92
- build: update zig version and c extern linkage by @arrufat in #93
- feat(python): add box blur method by @arrufat in #94
- feat(python): add Image.copy method by @arrufat in #95
- feat(python): add Image.sharpen method by @arrufat in #96
- refactor(rectangle)!: make bounds exclusive by @arrufat in #97
- feat(image): add insert method for image region placement by @arrufat in #98
- feat(python): add crop, extract, and insert methods by @arrufat in #99
- feat(image): add horizontal and vertical flip methods by @arrufat in #100
- feat(python): implement comparison for color types by @arrufat in #101
- feat(python): add psnr method by @arrufat in #102
- feature(python): add a file path for verbose error msg by @cih9088 in #103
- refactor(bindings): extract color utilities by @arrufat in #104
- feat(python): add image fill method by @arrufat in #105
- feat(python): add image view and is_view methods by @arrufat in #106
- docs(python): update readme with comprehensive examples by @arrufat in #107
- feat(image): add convolution and gaussian blur by @arrufat in #108
- feat(image): add difference of gaussians filter by @arrufat in #109
- feat(color)!: add advanced blending modes by @arrufat in #110
- feat(python): add blend method with blend modes by @arrufat in #111
- refactor(svd): separate static and dynamic SVD implementations by @arrufat in #112
- feat(font): refactor bitmap font system with dynamic unicode support by @arrufat in #113
- feat(python): add iteration and equality comparison by @arrufat in #114
- feat(python): allow int for extract size by @arrufat in #115
- feat(canvas): add arc drawing and filling functions by @arrufat in #116
- feat(python): add Python bindings for canvas arc by @arrufat in #117
- refactor(ArrayList): use ArrayList (unmanaged) by @arrufat in #118
- feat(perf): improve convolution and interpolation with channel separation by @arrufat in #119
- refactor(image)!: rename blur methods, add gaussian blur binding by @arrufat in #120
- feat: add ORB feature detection by @arrufat in #121
- feat(optimization): add Hungarian algorithm by @arrufat in #122
- feat(numeric): generalize matrix and assignment types by @arrufat in #123
- feat(image): add dupe method by @arrufat in #124
- feat(image): add multi-format support by @arrufat in #125
- refactor(image): make filtering stride-safe for views by @arrufat in #126
- feat(python): add image slice assignment and copy by @arrufat in #127
- refactor(image/filtering): refactor filtering and convolution helpers by @arrufat in #128
- refactor(image)!: rename image constructors by @arrufat in #129
- feat(python): add to_gray method to color types by @arrufat in #130
- fix(py/image): correctly detect Rgba objects for color init by @arrufat in #131
- refactor(python): generalize color parsing utility by @arrufat in #132
- refactor(python): streamline color bindings and validation by @arrufat in #133
- refactor(geometry): move color conversion to Point methods by @arrufat in #134
- feat(python-bindings): add Matrix type with NumPy interop by @arrufat in #135
- refactor(image): rename
isViewtoisContiguousby @arrufat in #136 - feat(python): add python bindings for assignment problem by @arrufat in #137
- build(python): include type stubs by @arrufat in #138
- feat(python): add optional blend mode to color.blend by @arrufat in #139
- feat(jpeg): add 4:4:4 chroma subsampling support by @arrufat in #140
- feat(jpeg): add 4:2:2 and 4:1:1 chroma subsampling by @arrufat in #142
- docs: fix typos by @kianmeng in #141
- feat(python) add sobel edge detection to Image class by @arrufat in #143
- refactor(pyimage): centralize PyImage creation and ownership by @arrufat in #144
- feat(python): add support for strided images in numpy interop by @arrufat in #145
- feat(python): enable direct pixel component assignment by @arrufat in #146
- test(python): consolidate binding tests to smoke tests by @arrufat in #147
- feat(image): add blend method for image compositing by @arrufat in #148
- refactor(image): make channel operations generic by @arrufat in #149
- feat(pixel-proxy): add color conversion and blend methods by @arrufat in #150
- feat(python): add motion blur image processing by @arrufat in #151
- refactor: rename InterpolationMethod enum to Interpolation by @arrufat in #152
- refactor(blending): rename BlendMode enum to Blending by @arrufat in #153
- feat(warp): add Image.warp and python transforms by @arrufat in #154
- feat(python): allow tuple for view rect parameter by @arrufat in #155
- refactor(display): rename ANSI terminal display modes to SGR by @arrufat in #156
- refactor(python): unify motion blur classes by @arrufat in #157
- feat(pca): add python bindings by @arrufat in #158
- refactor(image): split module into sub-modules by @arrufat in #159
- feat(image): add set_border method by @arrufat in #160
- feat(image): add get_rectangle method by @arrufat in #161
- fix(image): correct behavior of setBorder by @arrufat in #162
- feat(python): add iou/overlaps, extend intersect with tuple support by @arrufat in #163
- fix(python): don't allow None rectangle in Image.set_border by @arrufat in #164
- refactor(python): make transform init points mand...
zignal 0.4.1
Added
- add an example to showcase more drawing stuff
Fixed
Canvas.fillRectanglenow properly uses alpha blending in .soft modeCanvas.drawLinehas some fixes in the drawLineXiaolinWu algorithm
Full Changelog: 0.4.0...0.4.1
zignal 0.4.0
Highlights
This release introduces image scaling for terminal graphics (Sixel, Kitty)
and allows direct image instantiation in Python.
It also includes significant refactoring of terminal state management and
the Sixel processing pipeline, alongside performance optimizations for
Sixel color quantization and dithering. Python bindings received enhanced
docstrings and type hints.
BREAKING CHANGE: Canvas.drawText method parameter order changed from
(x, y, text, font, color) to (x, y, text, color, font).
PRs
- feat(python): allow image instantiation by @arrufat in #84
- feat(python)!: make draw_text font optional, bump Python to 3.10 by @arrufat in #85
- refactor(terminal): encapsulate state management by @arrufat in #86
- feat(image): allow sixel image scaling by @arrufat in #87
- feat(kitty): add image scaling support by @arrufat in #88
- chore(python-docs): improve docs build and URL by @arrufat in #89
Full Changelog: 0.3.0...0.4.0
zignal 0.3.0
Highlights
This release focuses on text rendering capabilities and significantly expands the Python bindings to provide a complete 2D graphics API. The font support enables rendering text in various bitmap formats, while the Python Canvas API brings drawing capabilities on par with the core library.
Core Improvements
- Unified Point syntax: Cleaner API with Point(2, f32) instead of Point2d(f32)
- Image scaling: New method for flexible image resizing
- PixelIterator: Sequential pixel traversal with view support
- Canvas bounds handling: Better clipping and edge case management
- Matrix enhancements: Improved numerical stability in decompositions
Font Support & Text Rendering
- New font system: Load and render text using PCF and BDF bitmap fonts
- Font compression: Automatic support for gzipped font files
- Built-in font: Default 8x8 font for immediate text rendering
- Canvas text drawing: Render text with optional antialiasing
Python Bindings - Major Expansion
- Canvas API: Complete 2D drawing primitives - lines, circles, polygons, rectangles, Bézier curves
- Geometry classes: Rectangle operations and ConvexHull computation
- Text rendering: BitmapFont class for rendering text in Python
- Enhanced Image class: Richer API with better Canvas integration
PRs
- feat(text): add bitmap font rendering and text drawing by @arrufat in #54
- feat(image): add pixel iterator for image traversal by @arrufat in #55
- feat(python): add resize method and interpolation enum by @arrufat in #56
- feat(image): add letterbox resizing function by @arrufat in #57
- refactor(matrix)!: move analysis methods to Matrix by @arrufat in #58
- feat(python): add canvas object for image drawing by @arrufat in #59
- feat(python): add draw_line method by @arrufat in #60
- refactor(py-stubs): use metadata for stub generation by @arrufat in #61
- refactor(python-bindings): centralize Python C API import by @arrufat in #62
- chore(python): consolidate dev dependencies and stub generation by @arrufat in #63
- feat(python): add pixel access to Image class by @arrufat in #64
- feat(font): add BDF font parsing and rendering by @arrufat in #66
- refactor(point)!: use tuple literal for construction and reorder parameters by @arrufat in #67
- refactor(fdm): restructure FDM to use stateful object by @arrufat in #68
- docs(python): reformat docstrings to markdown by @arrufat in #69
- chore(docs): enable stub file parsing for python docs by @arrufat in #70
- feat(python): allow integer for grayscale color input by @arrufat in #71
- Add a bit of detail in README by @cih9088 in #74
- build(python): improve macOS wheel portability by @arrufat in #73
- feat(font/pcf): add PCF font loading support by @arrufat in #75
- feat(font/bdf): support gzipped BDF font files by @arrufat in #76
- feat(font): add bdf font saving by @arrufat in #77
- feat(python): add drawing and filling methods to canvas by @arrufat in #78
- feat(bdf): add support for saving compressed files by @arrufat in #79
- refactor(color): simplify python color object creation by @arrufat in #80
- feat(image): add image scaling method by @arrufat in #81
- refactor(canvas): use comptime for draw methods by @arrufat in #82
- feat(python): add convex hull computation by @arrufat in #83
Full Changelog: 0.2.0...0.3.0
zignal 0.2.0
Highlights
- 2-5x faster image operations with SIMD-optimized RGBA kernels
- High-quality image interpolation - 6 algorithms including Lanczos and Mitchell
- Terminal graphics - Display images with Sixel, Kitty, Braille, and ANSI
- Python bindings - Zero-copy NumPy integration and rich display support
Core Library
New Features
- Image interpolation methods: nearest, bilinear, bicubic, Catmull-Rom, Lanczos, Mitchell
- Terminal display formats: Sixel, Kitty graphics protocol, Braille, ANSI blocks
- PNG color management and optimized filter selection
- Refactored image module into organized sub-modules
Performance
- SIMD kernels for RGBA operations (2-5x speedup)
- Optimized PNG encoding with adaptive filtering
- Memory-efficient implementations
Python Bindings
Breaking Change: Image class now uses RGBA storage internally (33% more memory, much faster)
New Features
- Feature Distribution Matching (FDM) for color transfer
- Zero-copy NumPy conversion with to_numpy()
- Jupyter notebook support with format
- Type stubs for better IDE support
- Pre-built wheels for Python 3.8-3.13
PRs
- feat(image): enable zero-copy numpy conversion by @arrufat in #43
- feat(python): add feature distribution matching bindings by @arrufat in #44
- perf(fdm): speedup operations and reduce allocations by @arrufat in #45
- refactor(python): move scripts and sources to subdirs by @arrufat in #46
- feat(sixel): add sixel support for images by @arrufat in #47
- feat(python): add
__format__method for display by @arrufat in #48 - feat(kitty): add kitty graphics protocol support by @arrufat in #49
- refactor(image): split monolithic module into sub-modules by @arrufat in #50
- feat(image): add image interpolation methods by @arrufat in #51
- perf(interpolation): add SIMD kernels for 4xu8 structs (Rgba) by @arrufat in #52
- feat(python)!: migrate to Image(Rgba) for SIMD performance by @arrufat in #53
Full Changelog: 0.1.0...0.2.0