# metastrip
[](https://crates.io/crates/metastrip)
[](https://docs.rs/metastrip)
[](https://github.com/deanchalk/metastrip)
A fast, safe Rust library for extracting and stripping metadata from image files.
## Features
- **Extract metadata** from images (EXIF, IPTC, XMP, ICC profiles)
- **Strip metadata** completely while preserving image quality (lossless)
- **Multiple formats**: JPEG, PNG, TIFF, WebP
- **Zero unsafe code**: Built with safety in mind
- **Fast**: Byte-level manipulation, no image decoding/encoding
- **Memory efficient**: Single-pass streaming approach
## Supported Formats
| JPEG | ✅ | ✅ | - |
| PNG | ✅ | ✅ | - |
| TIFF | ✅ | ✅ | Both (II/MM) |
| WebP | ✅ | ✅ | - |
## Supported Metadata Types
- **EXIF** - Camera settings, timestamps, GPS data
- **IPTC** - Photo journalism metadata (captions, keywords, copyright)
- **XMP** - Adobe extensible metadata (editing history, etc.)
- **ICC Color Profiles** - Color space information
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
metastrip = "0.1.0"
```
## Usage
### Extract Metadata
```rust
use metastrip;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Read image file
let image_data = std::fs::read("photo.jpg")?;
// Extract all metadata
let metadata = metastrip::extract_metadata(&image_data)?;
// Access different metadata types
if let Some(exif) = metadata.exif {
println!("Found {} EXIF fields", exif.fields.len());
for (key, value) in exif.fields {
println!("{}: {:?}", key, value);
}
}
if let Some(xmp) = metadata.xmp {
println!("XMP data: {}", xmp.raw_xml);
}
if let Some(icc) = metadata.icc_profile {
println!("ICC profile: {} bytes", icc.data.len());
if let Some(desc) = icc.description {
println!("Profile: {}", desc);
}
}
Ok(())
}
```
### Strip Metadata
```rust
use metastrip;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Read image file
let image_data = std::fs::read("photo.jpg")?;
// Strip all metadata (lossless operation)
let clean_image = metastrip::strip_metadata(&image_data)?;
// Save cleaned image
std::fs::write("photo_clean.jpg", clean_image)?;
// Verify metadata is removed
let metadata = metastrip::extract_metadata(&clean_image)?;
assert!(metadata.exif.is_none());
assert!(metadata.xmp.is_none());
Ok(())
}
```
## How It Works
### Lossless Stripping
Unlike tools that decode and re-encode images, `metastrip` operates at the byte level:
- **JPEG**: Parses segments, removes APP markers containing metadata
- **PNG**: Parses chunks, keeps only critical chunks (IHDR, PLTE, IDAT, IEND, tRNS)
- **TIFF**: Parses IFD structure, rebuilds with only essential tags
- **WebP**: Parses RIFF container, rebuilds without metadata chunks
This approach is:
- ✅ **Fast** - No expensive decode/encode operations
- ✅ **Lossless** - Preserves original image quality
- ✅ **Memory efficient** - Single-pass processing
## Performance
Metadata stripping is designed to be fast:
- Format detection: < 1µs
- JPEG strip (10MB): ~50ms
- PNG strip (10MB): ~100ms
- Zero-copy operations where possible
## API Documentation
### Main Functions
```rust
pub fn extract_metadata(bytes: &[u8]) -> Result<Metadata>
pub fn strip_metadata(bytes: &[u8]) -> Result<Vec<u8>>
```
### Types
```rust
pub struct Metadata {
pub format: ImageFormat,
pub exif: Option<ExifData>,
pub iptc: Option<IptcData>,
pub xmp: Option<XmpData>,
pub icc_profile: Option<IccProfile>,
}
pub enum ImageFormat {
Jpeg,
Png,
Tiff,
WebP,
}
```
See the [API documentation](https://docs.rs/metastrip) for complete details.
## Security
- ✅ **No unsafe code** - Built entirely with safe Rust
- ✅ **Bounds checking** - All array accesses are validated
- ✅ **Input validation** - File sizes, segment lengths, and offsets are checked
- ✅ **DoS protection** - Reasonable limits on metadata size
## Testing
The library includes comprehensive tests:
```bash
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_jpeg_stripping
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
## Acknowledgments
- [kamadak-exif](https://github.com/kamadak/exif-rs) - EXIF parsing
- [quick-xml](https://github.com/tafia/quick-xml) - XMP (XML) parsing