raw_preview_rs

Crates.ioraw_preview_rs
lib.rsraw_preview_rs
version0.1.2
created_at2025-08-05 19:20:19.806785+00
updated_at2025-08-15 18:48:58.463156+00
descriptionA Rust library for processing raw images to create fast previews and handling EXIF metadata.
homepage
repositoryhttps://github.com/mlgldl/raw_preview_rs
max_upload_size
id1782640
size168,393
Michael (mlgldl)

documentation

README

raw_preview_rs

Crates.io Documentation License Rust

A Rust library that quickly creates preview JPEGs from RAW image files and extracts EXIF metadata.

This crate statically links several C/C++ dependencies; building it requires native build tools (see below).

Features

  • RAW Image Processing: Supports 27+ RAW formats, including CR2, NEF, ARW, RAF, and more.
  • Standard Image Formats: Handles JPEG, PNG, TIFF, BMP, and WebP.
  • EXIF Metadata Extraction: Extracts and preserves EXIF metadata, including camera make, model, ISO, and more.
  • Resolution Reduction: Automatically reduces image resolution for fast previews.

Installation

Add this to your Cargo.toml:

[dependencies]
raw_preview_rs = "0.1.1"
# Run package tests
cargo test -p raw_preview_rs

# Build the package (release)
cargo build --manifest-path package/Cargo.toml --release

Usage

Example: Processing a RAW File

use raw_preview_rs::process_any_image;

match process_any_image("photo.cr2", "preview.jpg") {
    Ok(exif) => {
        println!("Processed: {} {}", exif.camera_make, exif.camera_model);
        println!("Settings: ISO {}, {}, {}",
                 exif.iso_speed, exif.formatted_aperture(), exif.formatted_shutter_speed());
    }
    Err(e) => eprintln!("Processing failed: {}", e),
}

Example: Processing a JPEG File

use raw_preview_rs::process_any_image;

match process_any_image("photo.jpg", "copy.jpg") {
    Ok(exif) => println!("JPEG processed: {}", exif.camera_model),
    Err(e) => eprintln!("JPEG processing failed: {}", e),
}

Example: In-memory API (bytes)

The crate now provides APIs that accept image data as bytes (no temporary files required). These are useful when images come from HTTP uploads, in-memory caches, or other non-filesystem sources.

Example: process a JPEG/PNG image provided as bytes:

use std::fs;
use raw_preview_rs::process_image_bytes;

let bytes = fs::read("photo.jpg").expect("read sample");
let exif = process_image_bytes(&bytes, "preview_out.jpg").expect("process bytes");
println!("Processed image: {} {}", exif.camera_make, exif.camera_model);

Example: convert RAW bytes (DNG/CR2/etc.) to JPEG:

use std::fs;
use raw_preview_rs::convert_raw_bytes_to_jpeg;

let raw_bytes = fs::read("sample.DNG").expect("read raw sample");
let exif = convert_raw_bytes_to_jpeg(&raw_bytes, "preview_raw_out.jpg").expect("convert raw bytes");
println!("RAW processed: {} {}", exif.camera_make, exif.camera_model);

Note: processing using the bytes-based API is performed entirely in-memory via the native FFI and does not create temporary files. The function will still write the resulting JPEG preview to the output_path you provide (i.e., you must supply a filesystem path where the preview will be saved).

If you prefer the preview JPEG bytes to be returned directly (instead of writing to disk), the crate exposes Vec-returning helpers at the crate root. Example usage:

use std::fs::File;
use std::io::Write;
use std::fs;
use raw_preview_rs::{process_image_bytes_to_vec, convert_raw_bytes_to_vec};

// Image file (JPEG/PNG/etc.) -> get JPEG bytes in-memory
let img_bytes = fs::read("test_pictures/test_jpeg.jpeg").expect("read sample");
let (jpeg_bytes, exif) = process_image_bytes_to_vec(&img_bytes).expect("process to vec");
File::create("preview_from_vec.jpg").unwrap().write_all(&jpeg_bytes).unwrap();
println!("Processed in-memory: {} {}", exif.camera_make, exif.camera_model);

// RAW file (DNG/CR2/etc.) -> get JPEG bytes in-memory
let raw_bytes = fs::read("test_pictures/test_raw.ARW").expect("read raw sample");
let (jpeg_bytes_raw, exif_raw) = convert_raw_bytes_to_vec(&raw_bytes).expect("convert raw to vec");
File::create("preview_raw_from_vec.jpg").unwrap().write_all(&jpeg_bytes_raw).unwrap();
println!("RAW in-memory: {} {}", exif_raw.camera_make, exif_raw.camera_model);

Supported Formats

RAW Formats (processed via LibRaw):

  • Canon: CR2, CR3
  • Nikon: NEF
  • Sony: ARW, SR2, SRF
  • Fujifilm: RAF
  • Panasonic: RW2
  • Olympus: ORF
  • Pentax: PEF, PTX
  • Samsung: SRW
  • Hasselblad: 3FR, FFF
  • Mamiya: MEF
  • Minolta: MRW, MDC
  • Sigma: X3F
  • Kodak: DCR, KDC
  • PhaseOne: IIQ, CAP
  • Leica: RWL
  • GoPro: GPR
  • Epson: ERF
  • Leaf: MOS
  • RED: R3D
  • Adobe: DNG
  • Generic: RAW

Standard Image Formats:

  • JPEG: JPG, JPEG
  • PNG: PNG
  • TIFF: TIFF, TIF
  • Bitmap: BMP
  • WebP: WEBP

Build Requirements

This library has several native dependencies that are automatically downloaded and built during compilation. To ensure a successful build, you need the following tools installed on your system:

Required Build Tools

All Platforms

  • CMake (version 3.10 or higher)

  • Make

    • Used for building all dependencies
    • Usually pre-installed on Unix-like systems

macOS

# Install Xcode Command Line Tools (includes make, clang, etc.)
xcode-select --install

# Install CMake using Homebrew
brew install cmake

# Install autotools (recommended for LibRaw)
brew install autoconf automake libtool pkg-config

Ubuntu/Debian

# Install build essentials and CMake
sudo apt update
sudo apt install build-essential cmake

# Install autotools (recommended for LibRaw)
sudo apt install autoconf automake libtool pkg-config

CentOS/RHEL/Fedora

# Install build tools and CMake
sudo yum groupinstall "Development Tools"
sudo yum install cmake

# Install autotools (recommended for LibRaw)
sudo yum install autoconf automake libtool pkgconfig

Windows

  • Visual Studio (2019 or later) with C++ build tools
  • CMake - Download from https://cmake.org/download/
  • Git (for downloading dependencies)

Alternatively, use vcpkg or Conan to manage dependencies.

Optional Tools

  • autoconf, automake, libtool: Recommended for building LibRaw from source
    • If these are not available, the build script will attempt to use pre-generated configure scripts
    • Without these tools, some LibRaw versions may fail to build

Build Troubleshooting

If you encounter build issues:

  1. Missing autotools: Install autoconf, automake, and libtool
  2. CMake not found: Ensure CMake is in your PATH
  3. Compiler errors: Ensure you have a C++11 compatible compiler
  4. Network issues: The build downloads dependencies from the internet

For detailed error messages, run:

RUST_BACKTRACE=1 cargo build

Cross-compilation

Cross-compilation is supported but requires the target platform's build tools. Ensure CMake and make are available for your target platform.

Dependencies

This library automatically manages all its native dependencies through a custom build script. The following libraries are downloaded, compiled, and statically linked during the build process:

Dependency Version Purpose Source
zlib 1.3 Compression library zlib.net
LibRaw 0.21.4 RAW image processing GitHub
libjpeg-turbo 2.1.5 JPEG compression/decompression GitHub
TinyEXIF 1.0.3 EXIF metadata extraction GitHub
TinyXML2 11.0.0 XML parsing for XMP metadata GitHub
stb_image latest Standard image format decoding GitHub

Dependency Management Features

  • Automatic Download: All dependencies are downloaded from their official sources
  • Version Pinning: Specific versions are used to ensure build reproducibility
  • Static Linking: All libraries are statically linked for easy deployment
  • Caching: Built dependencies are cached to speed up subsequent builds
  • Cross-platform: Works on macOS, Linux, and Windows with appropriate build tools

No manual dependency installation is required - just ensure you have the build tools listed above.

Disabling SIMD for libjpeg-turbo builds

By default SIMD optimizations are enabled for native builds. You can disable SIMD specifically for the bundled libjpeg-turbo build in two ways:

  • Disable via Cargo features (recommended):
# Build without the default "simd" feature
cargo build --no-default-features
  • Force-disable via environment variable:
# Example: disable SIMD for one build
RAW_PREVIEW_RS_DISABLE_SIMD=1 cargo build

When SIMD is disabled the build script will pass flags to the native build to avoid auto-vectorization (portable across compilers). This helps when building for targets that don't support the host's SIMD instruction set.

License

This project is licensed under the GNU General Public License (GPL) version 3. See the LICENSE file for details.

Commit count: 0

cargo fmt