https://github.com/dmtrkovalenko/odiff-cross
https://github.com/dmtrkovalenko/odiff-cross
Last synced: 9 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/dmtrkovalenko/odiff-cross
- Owner: dmtrKovalenko
- Created: 2025-09-06T11:52:04.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-09-06T13:11:26.000Z (9 months ago)
- Last Synced: 2025-09-06T13:29:37.022Z (9 months ago)
- Language: Zig
- Size: 72.8 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# zdiff
A fast pixel-by-pixel image comparison tool written in Zig. This is a faithful port of [odiff](https://github.com/dmtrKovalenko/odiff) from OCaml to Zig, maintaining full compatibility with the original API while leveraging Zig's performance and safety features.
## Features
- **Fast pixel-by-pixel image comparison** using perceptually accurate color difference algorithms
- **Antialiasing detection** to ignore antialiased pixels in comparisons
- **Multiple image format support** (PNG, JPEG, TIFF) via C FFI
- **Flexible output options** including diff masks and parseable output
- **Ignore regions** to exclude specific areas from comparison
- **Memory efficient** with configurable RAM usage optimization
- **Full CLI compatibility** with the original odiff
## Algorithm Details
### Color Difference Calculation
zdiff uses the YIQ color space for perceptually accurate color difference calculations:
- **YIQ Color Space**: Converts RGB to YIQ (luminance and chrominance) for better human perception matching
- **Semi-transparent Pixel Blending**: Properly handles alpha channel by blending with white background
- **Configurable Threshold**: Allows fine-tuning of sensitivity (0.0-1.0 range)
### Antialiasing Detection
The antialiasing detection algorithm identifies edge pixels that may appear different due to antialiasing:
- **Neighbor Analysis**: Examines 3x3 pixel neighborhoods around each different pixel
- **Brightness Delta Calculation**: Uses brightness differences to identify edge pixels
- **Sibling Counting**: Counts similar pixels in neighborhoods to detect antialiasing patterns
- **Cross-Image Validation**: Verifies antialiasing patterns exist in both images
## Installation
### Prerequisites
- Zig 0.14.1 or later
- Standard C library (for image format support)
### Building from Source
```bash
git clone
cd zdiff
zig build
```
The binary will be available at `zig-out/bin/zdiff`.
## Usage
### Basic Usage
```bash
# Compare two images
zdiff image1.png image2.png
# Compare and save diff output
zdiff image1.png image2.png diff.png
# Compare with custom threshold
zdiff image1.png image2.png -t 0.05
# Compare with antialiasing detection
zdiff image1.png image2.png --antialiasing
```
### Command Line Options
| Option | Description |
|--------|-------------|
| `-t, --threshold ` | Color difference threshold (0.0-1.0, default: 0.1) |
| `--diff-mask` | Output only changed pixels over transparent background |
| `--fail-on-layout` | Fail if image dimensions differ |
| `--parsable-stdout` | Machine-readable output format |
| `--diff-color ` | Color for highlighting differences (e.g., #cd2cc9) |
| `--aa, --antialiasing` | Ignore antialiased pixels in diff |
| `--output-diff-lines` | Output line numbers with differences |
| `--reduce-ram-usage` | Use less memory (slower) |
| `-i, --ignore ` | Ignore regions (format: x1:y1-x2:y2,x3:y3-x4:y4) |
| `-h, --help` | Show help message |
| `--version` | Show version |
### Exit Codes
- `0` - Images match
- `21` - Layout difference (when --fail-on-layout is used)
- `22` - Pixel differences found
### Examples
#### Compare with ignore regions
```bash
zdiff image1.png image2.png -i "10:10-50:50,100:100-200:200"
```
#### Parseable output for CI/CD
```bash
zdiff image1.png image2.png --parsable-stdout
# Output: number of different pixels or "layout" for dimension mismatch
```
#### Antialiasing-aware comparison
```bash
# Ignore antialiased pixels (useful for font rendering comparisons)
zdiff text1.png text2.png --antialiasing
```
## Architecture
### Core Components
1. **Image I/O** (`src/image_io.zig`)
- Abstraction layer over C image libraries
- Support for PNG, JPEG, and TIFF formats
- Memory-safe wrappers around C FFI
2. **Diff Algorithm** (`src/diff.zig`)
- Core pixel comparison logic
- YIQ color space conversion
- Difference calculation and thresholding
3. **Antialiasing Detection** (`src/antialiasing.zig`)
- Sophisticated edge detection
- Neighborhood analysis
- Cross-image pattern validation
4. **Color Delta** (`src/color_delta.zig`)
- Perceptual color difference calculations
- Alpha blending with white background
- YIQ color space transformations
5. **CLI Interface** (`src/cli.zig`)
- Command-line argument parsing
- Compatible with original odiff API
- Comprehensive help and error messages
6. **C Bindings** (`c_bindings/`)
- FFI layer for image format support
- Memory management for C structures
- Placeholder implementations (can be extended with full libpng/libjpeg/libtiff)
### Memory Management
- **RAII Pattern**: All resources automatically cleaned up via Zig's defer mechanism
- **Arena Allocators**: Efficient memory allocation patterns
- **C Interop**: Safe wrappers around C memory management
## Compatibility with odiff
zdiff maintains full API compatibility with the original odiff:
- **Same command-line arguments and flags**
- **Identical exit codes**
- **Same output formats**
- **Compatible ignore region syntax**
- **Equivalent algorithmic behavior**
This makes zdiff a drop-in replacement for odiff in existing scripts and CI/CD pipelines.
## Performance
zdiff is designed for performance:
- **Compiled to native code** via Zig's LLVM backend
- **Zero-cost abstractions** with compile-time optimization
- **Memory-efficient algorithms** with configurable RAM usage
- **SIMD potential** for future vectorization optimizations
## Development
### Project Structure
```
zdiff/
├── src/
│ ├── main.zig # CLI entry point
│ ├── root.zig # Library exports
│ ├── image_io.zig # Image loading/saving
│ ├── diff.zig # Core diff algorithm
│ ├── antialiasing.zig # Antialiasing detection
│ ├── color_delta.zig # Color difference calculation
│ ├── cli.zig # Command-line interface
│ └── c_bindings.zig # C FFI wrappers
├── c_bindings/
│ ├── zdiff_io.h # C header definitions
│ └── zdiff_io.c # C implementation (placeholder)
├── build.zig # Build configuration
└── README.md
```
### Building and Testing
```bash
# Build debug version
zig build
# Build optimized release
zig build -Doptimize=ReleaseFast
# Run tests
zig build test
# Run with arguments
zig build run -- image1.png image2.png
```
### Extending Image Format Support
To add support for additional image formats:
1. Implement C functions in `c_bindings/zdiff_io.c`
2. Add format detection in `src/image_io.zig`
3. Create wrapper functions in `src/c_bindings.zig`
4. Update build.zig to link required libraries
## Future Enhancements
- **Full image library integration** (replace placeholder C implementations)
- **SIMD optimizations** for faster pixel processing
- **Parallel processing** for large images
- **Additional output formats** (JSON, XML)
- **Web Assembly target** for browser usage
- **Integration with zig-cli library** for better argument parsing
## License
This project maintains the same license as the original odiff project.
## Contributing
Contributions are welcome! Please ensure:
- Code follows Zig formatting conventions
- All tests pass
- New features include appropriate tests
- Documentation is updated for API changes
## Acknowledgments
- Original [odiff](https://github.com/dmtrKovalenko/odiff) project by Dmitriy Kovalenko
- The Zig programming language community
- Contributors to the image processing libraries used