Download libraries/rawkit/src/metadata/camera_data.rs from openfree/graphite2: direct link, hf CLI and curl.
- Browser
- Download file 2.77 kB
-
https://huggingface.co/spaces/openfree/graphite2/resolve/main/libraries/rawkit/src/metadata/camera_data.rs
- Command line
-
hf download hf://spaces/openfree/graphite2/libraries/rawkit/src/metadata/camera_data.rs
-
curl -L -o camera_data.rs https://huggingface.co/spaces/openfree/graphite2/resolve/main/libraries/rawkit/src/metadata/camera_data.rs
2.77 kB
| use crate::RawImage; | |
| use rawkit_proc_macros::build_camera_data; | |
| pub struct CameraData { | |
| pub black: u16, | |
| pub maximum: u16, | |
| pub xyz_to_camera: [i16; 9], | |
| } | |
| impl CameraData { | |
| const DEFAULT: CameraData = CameraData { | |
| black: 0, | |
| maximum: 0, | |
| xyz_to_camera: [0; 9], | |
| }; | |
| } | |
| const CAMERA_DATA: [(&str, CameraData); 40] = build_camera_data!(); | |
| const RGB_TO_XYZ: [[f64; 3]; 3] = [ | |
| // Matrix: | |
| [0.412453, 0.357580, 0.180423], | |
| [0.212671, 0.715160, 0.072169], | |
| [0.019334, 0.119193, 0.950227], | |
| ]; | |
| impl RawImage { | |
| pub fn calculate_conversion_matrices(&mut self) { | |
| let Some(ref camera_model) = self.camera_model else { return }; | |
| let camera_name_needle = camera_model.make.to_owned() + " " + &camera_model.model; | |
| let xyz_to_camera = CAMERA_DATA | |
| .iter() | |
| .find(|(camera_name_haystack, _)| camera_name_needle == *camera_name_haystack) | |
| .map(|(_, data)| data.xyz_to_camera.map(|x| (x as f64) / 10_000.)); | |
| let Some(xyz_to_camera) = xyz_to_camera else { return }; | |
| let mut rgb_to_camera = [[0.; 3]; 3]; | |
| for i in 0..3 { | |
| for j in 0..3 { | |
| for k in 0..3 { | |
| rgb_to_camera[i][j] += RGB_TO_XYZ[k][j] * xyz_to_camera[i * 3 + k]; | |
| } | |
| } | |
| } | |
| let white_balance_multiplier = rgb_to_camera.map(|x| 1. / x.iter().sum::<f64>()); | |
| for (index, row) in rgb_to_camera.iter_mut().enumerate() { | |
| *row = row.map(|x| x * white_balance_multiplier[index]); | |
| } | |
| let camera_to_rgb = transpose(pseudoinverse(rgb_to_camera)); | |
| let cfa_white_balance_multiplier = if let Some(white_balance) = self.camera_white_balance { | |
| white_balance | |
| } else { | |
| self.cfa_pattern.map(|index| white_balance_multiplier[index as usize]) | |
| }; | |
| self.white_balance = Some(cfa_white_balance_multiplier); | |
| self.camera_to_rgb = Some(camera_to_rgb); | |
| } | |
| } | |
| fn pseudoinverse<const N: usize>(matrix: [[f64; 3]; N]) -> [[f64; 3]; N] { | |
| let mut output_matrix = [[0.; 3]; N]; | |
| let mut work = [[0.; 6]; 3]; | |
| for i in 0..3 { | |
| for j in 0..6 { | |
| work[i][j] = if j == i + 3 { 1. } else { 0. }; | |
| } | |
| for j in 0..3 { | |
| for k in 0..N { | |
| work[i][j] += matrix[k][i] * matrix[k][j]; | |
| } | |
| } | |
| } | |
| for i in 0..3 { | |
| let num = work[i][i]; | |
| for j in 0..6 { | |
| work[i][j] /= num; | |
| } | |
| for k in 0..3 { | |
| if k == i { | |
| continue; | |
| } | |
| let num = work[k][i]; | |
| for j in 0..6 { | |
| work[k][j] -= work[i][j] * num; | |
| } | |
| } | |
| } | |
| for i in 0..N { | |
| for j in 0..3 { | |
| output_matrix[i][j] = 0.; | |
| for k in 0..3 { | |
| output_matrix[i][j] += work[j][k + 3] * matrix[i][k]; | |
| } | |
| } | |
| } | |
| output_matrix | |
| } | |
| fn transpose<const N: usize>(matrix: [[f64; 3]; N]) -> [[f64; N]; 3] { | |
| let mut output_matrix = [[0.; N]; 3]; | |
| for (i, row) in matrix.iter().enumerate() { | |
| for (j, &value) in row.iter().enumerate() { | |
| output_matrix[j][i] = value; | |
| } | |
| } | |
| output_matrix | |
| } | |