Changelog
All notable changes to Puhu will be documented here.
The format is based on Keep a Changelog.
Version 0.4.1
Changed
crop()rewritten with row-by-rowmemcpyfor all common pixel formats (L, LA, RGB, RGBA), replacing the previous pixel-by-pixel iteration viaimage::crop_imm; now 1.1–3.7× faster than Pillow across image sizessplit()rewritten with a single-pass unsafe deinterleave that pre-allocates output buffers and usesiter_mut()to prove non-aliasing to LLVM, enabling paired SIMD loads; 1.3–5.1× faster than Pillow across all modes and sizesInternal refactor:
crop_rawmoved toutilsmodule, band deinterleave logic extracted toconversions::split_bands— no API changes
Fixed
Fixed a type error in 16-bit grayscale (
ImageLuma16) crop that caused a compile failure when operating onI-mode images loaded from 16-bit files
Version 0.4.0
Added
- Python 3.14 added to CI test matrix and pyproject.toml classifiers
- split() method — split an image into its individual bands:
- Returns a tuple[Image, ...] matching Pillow’s exact return type
- Each band is an independent L-mode (grayscale) copy
- Supported for all modes: L, LA, RGB, RGBA
- GIL released during channel extraction; LLVM-vectorisable hot path
- getbands() method — return band name tuple (e.g. ('R', 'G', 'B'))
- Image.new() now accepts 2-tuple (luma, alpha) color for LA mode images
Version 0.3.0
Added
paste()method for image composition with full Pillow compatibility:2-tuple and 4-tuple box coordinates
Negative coordinates with automatic clipping
Color fills via RGB/RGBA tuples, single integers, or color strings
Mask-based alpha blending
Abbreviated syntax
paste(im, mask)Automatic mode conversion between source and destination
Version 0.2.2
Added
Comprehensive documentation on ReadTheDocs
Enhanced error messages with coordinate information
Improved crop bounds validation
Changed
Updated PyO3 from 0.19 to 0.22
Improved memory efficiency by removing unnecessary clones
Enhanced error propagation in getter methods
Fixed
Fixed memory inefficiency in LazyImage::Bytes loading
Fixed inconsistent mutability in getter methods
Removed redundant unreachable patterns
Version 0.2.0
Added
rotate()method for 90°, 180°, 270° rotationstranspose()method for flipping operationsthumbnail()method for in-place resizingcopy()method for creating image copiesSupport for WEBP format
Support for TIFF format
Support for GIF format
Changed
Improved resize performance
Better error handling across all operations
Fixed
Fixed crop bounds validation
Fixed color conversion edge cases
Version 0.1.0
Added
Initial release
Core image operations:
open(),save(),new()Basic transformations:
resize(),crop()Support for PNG, JPEG, BMP formats
RGB, RGBA, and L (grayscale) modes
Resampling filters: NEAREST, BILINEAR, BICUBIC
Pillow-compatible API
Cross-platform wheels (Linux, macOS, Windows)
Upcoming Features
Planned for Next Release
merge()for combining bands back into a multi-channel imagefromarray()for NumPy integrationgetpixel()/putpixel()for direct pixel accessAdditional image modes
Under Consideration
filter()operations (blur, sharpen, etc.)getpixel()andputpixel()for pixel accessconvert()for mode conversionEXIF metadata support
Animated GIF support
Migration Notes
From 0.1.x to 0.2.x
Breaking Changes: None
New Features: The 0.2.x series adds new methods while maintaining full backward compatibility with 0.1.x.
Recommended Actions:
Update to 0.2.x for performance improvements
Start using new methods like
rotate()andtranspose()Update error handling to use improved error messages
Contributing
See Contributing to Puhu for information on how to contribute features or bug fixes.
Release Process
For maintainers, see .github/RELEASE.md for the complete release workflow.