Skip to main content

RawImageBuilder

Struct RawImageBuilder 

Source
pub struct RawImageBuilder {
    pub raw: RawMetadataBuilder,
    pub camera: CameraBuilder,
    pub lens: LensBuilder,
    /* private fields */
}
Expand description

Builder pattern for creating RAW images with ergonomic dot notation

§Example

use vsf::builders::RawImageBuilder; use vsf::types::BitPackedTensor;

let samples: Vec<u64> = vec![2048; 4096 * 3072]; let image = BitPackedTensor::pack(12, vec![4096, 3072], &samples);

let mut raw = RawImageBuilder::new(image); raw.camera.iso_speed = Some(800.0); raw.camera.shutter_time_s = Some(1.0 / 60.0); raw.raw.cfa_pattern = Some(vec![b'R', b'G', b'G', b'B']); raw.lens.make = Some("Sony".to_string());

let bytes = raw.build()?;

Fields§

§raw: RawMetadataBuilder§camera: CameraBuilder§lens: LensBuilder

Implementations§

Source§

impl RawImageBuilder

Source

pub fn new(image: BitPackedTensor) -> Self

Create a new RawImageBuilder with the image data

Examples found in repository?
examples/builder_pattern_example.rs (line 14)
8fn main() {
9    // Create a simple 8x8 test image
10    let samples: Vec<u64> = (0..64).map(|i| i * 4).collect(); // 0, 4, 8, 12, ..., 252
11    let image = BitPackedTensor::pack(8, vec![8, 8], &samples);
12
13    // Create builder with image
14    let mut raw = RawImageBuilder::new(image);
15
16    // Set RAW metadata fields using dot notation
17    raw.raw.cfa_pattern = Some(vec![b'R', b'G', b'G', b'B']); // RGGB Bayer pattern
18    raw.raw.black_level = Some(64.0);
19    raw.raw.white_level = Some(255.0);
20
21    // Set camera settings using dot notation
22    raw.camera.iso_speed = Some(800.0);
23    raw.camera.shutter_time_s = Some(1.0 / 60.0); // 1/60 second
24    raw.camera.aperture_f_number = Some(2.8);
25    raw.camera.focal_length_m = Some(0.050); // 50mm
26    raw.camera.focus_distance_m = Some(3.5);
27    raw.camera.flash_fired = Some(false);
28    raw.camera.metering_mode = Some("matrix".to_string());
29
30    // Set lens info using dot notation
31    raw.lens.make = Some("Sony".to_string());
32    raw.lens.model = Some("FE 50mm F1.2 GM".to_string());
33    raw.lens.min_focal_length_m = Some(0.050); // 50mm prime
34    raw.lens.max_focal_length_m = Some(0.050);
35    raw.lens.max_aperture_f = Some(1.2); // f/1.2 maximum aperture
36
37    // Build the VSF file
38    let bytes = raw.build().expect("Failed to build VSF file");
39
40    // Write to file
41    std::fs::write("builder_example.vsf", &bytes).expect("Failed to write file");
42
43    println!("Created builder_example.vsf ({} bytes)", bytes.len());
44    println!("\nThe builder pattern allows you to:");
45    println!("  - Use intuitive dot notation: raw.camera.iso_speed = Some(800.0)");
46    println!("  - Incrementally set fields based on conditions");
47    println!("  - Skip optional fields easily (they default to None)");
48}
More examples
Hide additional examples
examples/create_raw_image.rs (line 44)
4fn main() -> Result<(), String> {
5    println!("=== VSF RAW Image Example ===\n");
6
7    // Example: 17x163 11-bit single-plane RGGB bayer sensor
8    let width = 17;
9    let height = 163;
10    let planes = 1;
11    let bits = 11;
12    let cfa = vec![b'R', b'G', b'C', b'Y']; // Red Green Cyan Yellow Bayer pattern
13    let blackpoint = 499;
14    let whitepoint = 8047;
15
16    println!("Sensor specs:");
17    println!("  Resolution: {}×{} (single plane)", width, height);
18    println!("  Bit depth: {} bits per sample", bits);
19    println!("  CFA pattern: RGCY (Red, Green, Cyan, Yellow)");
20    println!("  Black level: {}", blackpoint);
21    println!("  White level: {}\n", whitepoint);
22
23    // Generate simulated RAW sensor data
24    let total_samples = width * height * planes;
25    let mut samples = Vec::with_capacity(total_samples);
26    let mut rng = 0usize;
27    for sample in 0..total_samples {
28        rng ^= rng.rotate_left(13).wrapping_add(sample);
29        let value = rng as u8 as u16 + blackpoint; // Simulate RAW image data
30        samples.push(value);
31    }
32
33    // Pack into BitPackedTensor (efficient storage for 11-bit samples)
34    let image = BitPackedTensor::pack(bits, vec![width, height], &samples);
35    println!(
36        "Packed {} samples into {} bytes\n",
37        total_samples,
38        image.data.len()
39    );
40
41    // ========== BUILDER PATTERN API ========== The builder accepts raw types for ergonomics - validation happens at build() time
42    println!("Building VSF RAW image with metadata...");
43
44    let mut raw = RawImageBuilder::new(image);
45
46    // Set RAW metadata (sensor characteristics) Builder fields accept simple types - they get validated and wrapped when you call build()
47    raw.raw.cfa_pattern = Some(cfa);
48    raw.raw.black_level = Some(blackpoint as f32);
49    raw.raw.white_level = Some(whitepoint as f32);
50    raw.raw.magic_9 = Some(vec![
51        1.5, -0.3, -0.2, // Sensor RGB → LMS colour matrix (3×3)
52        -0.4, 1.6, -0.2, -0.1, -0.5, 1.6,
53    ]);
54
55    // Set camera settings
56    raw.camera.make = Some("Sony".to_string());
57    raw.camera.model = Some("α7 IV".to_string());
58    raw.camera.serial_number = Some("87654321".to_string());
59    raw.camera.iso_speed = Some(800.);
60    raw.camera.shutter_time_s = Some(1. / 60.); // 1/60 second
61    raw.camera.aperture_f_number = Some(2.8);
62    raw.camera.focal_length_m = Some(0.024); // 24mm = 0.024m
63    raw.camera.exposure_compensation = Some(0.);
64    raw.camera.focus_distance_m = Some(5.);
65    raw.camera.flash_fired = Some(false);
66    raw.camera.metering_mode = Some("matrix".to_string());
67
68    // Set lens info
69    raw.lens.make = Some("Sony".to_string());
70    raw.lens.model = Some("FE 24mm F2.8 G".to_string());
71    raw.lens.serial_number = Some("12345678".to_string());
72    raw.lens.min_focal_length_m = Some(0.024); // Prime lens
73    raw.lens.max_focal_length_m = Some(0.024);
74    raw.lens.min_aperture_f = Some(2.8);
75    raw.lens.max_aperture_f = Some(22.);
76
77    // Build validates all fields and wraps them in type-safe newtypes This is where validation errors would surface (e.g., invalid CFA colour codes)
78    let raw_bytes = raw.build()?;
79
80    println!("✓ Built VSF RAW image: {} bytes", raw_bytes.len());
81    println!("  (Includes mandatory BLAKE3 hash for integrity)\n");
82
83    // Write to file
84    std::fs::write("example_raw.vsf", &raw_bytes).expect("Failed to write file");
85    println!("✓ Saved to example_raw.vsf");
86
87    println!("\n=== Complete! ===");
88    println!("The RAW image includes:");
89    println!("  • Bitpacked sensor data ({}-bit samples)", bits);
90    println!("  • CFA pattern (RGCY Bayer)");
91    println!("  • Black/white levels");
92    println!("  • Colour transformation matrix (Magic 9)");
93    println!("  • Camera information (make, model, S/N, ISO, shutter, aperture, etc.)");
94    println!("  • Lens information (make, model, S/N, focal length range, etc.)");
95    println!("  • Mandatory BLAKE3 file hash (automatic)");
96    println!("\nAll metadata is validated and type-checked at compile time.");
97    println!("Try changing a value to something invalid - the compiler will catch it!");
98
99    Ok(())
100}
Source

pub fn build(self) -> Result<Vec<u8>, String>

Build the complete VSF RAW image file

Examples found in repository?
examples/builder_pattern_example.rs (line 38)
8fn main() {
9    // Create a simple 8x8 test image
10    let samples: Vec<u64> = (0..64).map(|i| i * 4).collect(); // 0, 4, 8, 12, ..., 252
11    let image = BitPackedTensor::pack(8, vec![8, 8], &samples);
12
13    // Create builder with image
14    let mut raw = RawImageBuilder::new(image);
15
16    // Set RAW metadata fields using dot notation
17    raw.raw.cfa_pattern = Some(vec![b'R', b'G', b'G', b'B']); // RGGB Bayer pattern
18    raw.raw.black_level = Some(64.0);
19    raw.raw.white_level = Some(255.0);
20
21    // Set camera settings using dot notation
22    raw.camera.iso_speed = Some(800.0);
23    raw.camera.shutter_time_s = Some(1.0 / 60.0); // 1/60 second
24    raw.camera.aperture_f_number = Some(2.8);
25    raw.camera.focal_length_m = Some(0.050); // 50mm
26    raw.camera.focus_distance_m = Some(3.5);
27    raw.camera.flash_fired = Some(false);
28    raw.camera.metering_mode = Some("matrix".to_string());
29
30    // Set lens info using dot notation
31    raw.lens.make = Some("Sony".to_string());
32    raw.lens.model = Some("FE 50mm F1.2 GM".to_string());
33    raw.lens.min_focal_length_m = Some(0.050); // 50mm prime
34    raw.lens.max_focal_length_m = Some(0.050);
35    raw.lens.max_aperture_f = Some(1.2); // f/1.2 maximum aperture
36
37    // Build the VSF file
38    let bytes = raw.build().expect("Failed to build VSF file");
39
40    // Write to file
41    std::fs::write("builder_example.vsf", &bytes).expect("Failed to write file");
42
43    println!("Created builder_example.vsf ({} bytes)", bytes.len());
44    println!("\nThe builder pattern allows you to:");
45    println!("  - Use intuitive dot notation: raw.camera.iso_speed = Some(800.0)");
46    println!("  - Incrementally set fields based on conditions");
47    println!("  - Skip optional fields easily (they default to None)");
48}
More examples
Hide additional examples
examples/create_raw_image.rs (line 78)
4fn main() -> Result<(), String> {
5    println!("=== VSF RAW Image Example ===\n");
6
7    // Example: 17x163 11-bit single-plane RGGB bayer sensor
8    let width = 17;
9    let height = 163;
10    let planes = 1;
11    let bits = 11;
12    let cfa = vec![b'R', b'G', b'C', b'Y']; // Red Green Cyan Yellow Bayer pattern
13    let blackpoint = 499;
14    let whitepoint = 8047;
15
16    println!("Sensor specs:");
17    println!("  Resolution: {}×{} (single plane)", width, height);
18    println!("  Bit depth: {} bits per sample", bits);
19    println!("  CFA pattern: RGCY (Red, Green, Cyan, Yellow)");
20    println!("  Black level: {}", blackpoint);
21    println!("  White level: {}\n", whitepoint);
22
23    // Generate simulated RAW sensor data
24    let total_samples = width * height * planes;
25    let mut samples = Vec::with_capacity(total_samples);
26    let mut rng = 0usize;
27    for sample in 0..total_samples {
28        rng ^= rng.rotate_left(13).wrapping_add(sample);
29        let value = rng as u8 as u16 + blackpoint; // Simulate RAW image data
30        samples.push(value);
31    }
32
33    // Pack into BitPackedTensor (efficient storage for 11-bit samples)
34    let image = BitPackedTensor::pack(bits, vec![width, height], &samples);
35    println!(
36        "Packed {} samples into {} bytes\n",
37        total_samples,
38        image.data.len()
39    );
40
41    // ========== BUILDER PATTERN API ========== The builder accepts raw types for ergonomics - validation happens at build() time
42    println!("Building VSF RAW image with metadata...");
43
44    let mut raw = RawImageBuilder::new(image);
45
46    // Set RAW metadata (sensor characteristics) Builder fields accept simple types - they get validated and wrapped when you call build()
47    raw.raw.cfa_pattern = Some(cfa);
48    raw.raw.black_level = Some(blackpoint as f32);
49    raw.raw.white_level = Some(whitepoint as f32);
50    raw.raw.magic_9 = Some(vec![
51        1.5, -0.3, -0.2, // Sensor RGB → LMS colour matrix (3×3)
52        -0.4, 1.6, -0.2, -0.1, -0.5, 1.6,
53    ]);
54
55    // Set camera settings
56    raw.camera.make = Some("Sony".to_string());
57    raw.camera.model = Some("α7 IV".to_string());
58    raw.camera.serial_number = Some("87654321".to_string());
59    raw.camera.iso_speed = Some(800.);
60    raw.camera.shutter_time_s = Some(1. / 60.); // 1/60 second
61    raw.camera.aperture_f_number = Some(2.8);
62    raw.camera.focal_length_m = Some(0.024); // 24mm = 0.024m
63    raw.camera.exposure_compensation = Some(0.);
64    raw.camera.focus_distance_m = Some(5.);
65    raw.camera.flash_fired = Some(false);
66    raw.camera.metering_mode = Some("matrix".to_string());
67
68    // Set lens info
69    raw.lens.make = Some("Sony".to_string());
70    raw.lens.model = Some("FE 24mm F2.8 G".to_string());
71    raw.lens.serial_number = Some("12345678".to_string());
72    raw.lens.min_focal_length_m = Some(0.024); // Prime lens
73    raw.lens.max_focal_length_m = Some(0.024);
74    raw.lens.min_aperture_f = Some(2.8);
75    raw.lens.max_aperture_f = Some(22.);
76
77    // Build validates all fields and wraps them in type-safe newtypes This is where validation errors would surface (e.g., invalid CFA colour codes)
78    let raw_bytes = raw.build()?;
79
80    println!("✓ Built VSF RAW image: {} bytes", raw_bytes.len());
81    println!("  (Includes mandatory BLAKE3 hash for integrity)\n");
82
83    // Write to file
84    std::fs::write("example_raw.vsf", &raw_bytes).expect("Failed to write file");
85    println!("✓ Saved to example_raw.vsf");
86
87    println!("\n=== Complete! ===");
88    println!("The RAW image includes:");
89    println!("  • Bitpacked sensor data ({}-bit samples)", bits);
90    println!("  • CFA pattern (RGCY Bayer)");
91    println!("  • Black/white levels");
92    println!("  • Colour transformation matrix (Magic 9)");
93    println!("  • Camera information (make, model, S/N, ISO, shutter, aperture, etc.)");
94    println!("  • Lens information (make, model, S/N, focal length range, etc.)");
95    println!("  • Mandatory BLAKE3 file hash (automatic)");
96    println!("\nAll metadata is validated and type-checked at compile time.");
97    println!("Try changing a value to something invalid - the compiler will catch it!");
98
99    Ok(())
100}

Trait Implementations§

Source§

impl Clone for RawImageBuilder

Source§

fn clone(&self) -> RawImageBuilder

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RawImageBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.