@@ -3,10 +3,12 @@ pub mod demosaicing;
33pub mod metadata;
44pub mod postprocessing;
55pub mod preprocessing;
6+ pub mod processing;
67pub mod tiff;
78
89use crate :: metadata:: identify:: CameraModel ;
910
11+ use processing:: { Pixel , PixelTransform , RawPixel , RawPixelTransform } ;
1012use tag_derive:: Tag ;
1113use tiff:: file:: TiffRead ;
1214use tiff:: tags:: { Compression , ImageLength , ImageWidth , Orientation , StripByteCounts , SubIfd , Tag } ;
@@ -16,6 +18,9 @@ use tiff::{Ifd, TiffError};
1618use std:: io:: { Read , Seek } ;
1719use thiserror:: Error ;
1820
21+ pub const CHANNELS_IN_RGB : usize = 3 ;
22+ pub type Histogram = [ [ usize ; 0x2000 ] ; CHANNELS_IN_RGB ] ;
23+
1924pub enum SubtractBlack {
2025 None ,
2126 Value ( u16 ) ,
@@ -31,8 +36,8 @@ pub struct RawImage {
3136 pub maximum : u16 ,
3237 pub black : SubtractBlack ,
3338 pub camera_model : Option < CameraModel > ,
34- pub camera_white_balance_multiplier : Option < [ f64 ; 4 ] > ,
35- pub white_balance_multiplier : Option < [ f64 ; 4 ] > ,
39+ pub camera_white_balance : Option < [ f64 ; 4 ] > ,
40+ pub white_balance : Option < [ f64 ; 4 ] > ,
3641 pub camera_to_rgb : Option < [ [ f64 ; 3 ] ; 3 ] > ,
3742 pub rgb_to_camera : Option < [ [ f64 ; 3 ] ; 3 ] > ,
3843}
@@ -45,8 +50,6 @@ pub struct Image<T> {
4550 /// See <https://github.com/GraphiteEditor/Graphite/pull/1923#discussion_r1725070342> for more information.
4651 pub channels : u8 ,
4752 pub transform : Transform ,
48- pub rgb_to_camera : Option < [ [ f64 ; 3 ] ; 3 ] > ,
49- pub ( crate ) histogram : Option < [ [ usize ; 0x2000 ] ; 3 ] > ,
5053}
5154
5255#[ allow( dead_code) ]
@@ -84,6 +87,8 @@ pub fn decode<R: Read + Seek>(reader: &mut R) -> Result<RawImage, DecoderError>
8487 raw_image. camera_model = Some ( camera_model) ;
8588 raw_image. transform = transform;
8689
90+ raw_image. calculate_conversion_matrices ( ) ;
91+
8792 Ok ( raw_image)
8893}
8994
@@ -96,19 +101,94 @@ pub fn process_8bit(raw_image: RawImage) -> Image<u8> {
96101 width : image. width ,
97102 height : image. height ,
98103 transform : image. transform ,
99- rgb_to_camera : image. rgb_to_camera ,
100- histogram : image. histogram ,
101104 }
102105}
103106
104107pub fn process_16bit ( raw_image : RawImage ) -> Image < u16 > {
105- let raw_image = crate :: preprocessing:: camera_data:: calculate_conversion_matrices ( raw_image) ;
106- let raw_image = crate :: preprocessing:: subtract_black:: subtract_black ( raw_image) ;
107- let raw_image = crate :: preprocessing:: scale_colors:: scale_colors ( raw_image) ;
108- let image = crate :: demosaicing:: linear_demosaicing:: linear_demosaic ( raw_image) ;
109- let image = crate :: postprocessing:: convert_to_rgb:: convert_to_rgb ( image) ;
110- let image = crate :: postprocessing:: transform:: transform ( image) ;
111- crate :: postprocessing:: gamma_correction:: gamma_correction ( image)
108+ let subtract_black = raw_image. subtract_black_fn ( ) ;
109+ let scale_white_balance = raw_image. scale_white_balance_fn ( ) ;
110+ let scale_to_16bit = raw_image. scale_to_16bit_fn ( ) ;
111+ let raw_image = raw_image. apply ( ( subtract_black, scale_white_balance, scale_to_16bit) ) ;
112+
113+ let convert_to_rgb = raw_image. convert_to_rgb_fn ( ) ;
114+ let mut record_histogram = raw_image. record_histogram_fn ( ) ;
115+ let image = raw_image. demosaic_and_apply ( ( convert_to_rgb, & mut record_histogram) ) ;
116+
117+ let gamma_correction = image. gamma_correction_fn ( & record_histogram. histogram ) ;
118+ if image. transform == Transform :: Horizontal {
119+ image. apply ( gamma_correction)
120+ } else {
121+ image. transform_and_apply ( gamma_correction)
122+ }
123+ }
124+
125+ impl RawImage {
126+ pub fn apply ( mut self , mut transform : impl RawPixelTransform ) -> RawImage {
127+ for ( index, value) in self . data . iter_mut ( ) . enumerate ( ) {
128+ let pixel = RawPixel {
129+ value : * value,
130+ row : index / self . width ,
131+ column : index % self . width ,
132+ } ;
133+ * value = transform. apply ( pixel) ;
134+ }
135+
136+ self
137+ }
138+
139+ pub fn demosaic_and_apply ( self , mut transform : impl PixelTransform ) -> Image < u16 > {
140+ let mut image = vec ! [ 0 ; self . width * self . height * 3 ] ;
141+ for Pixel { values, row, column } in self . linear_demosaic_iter ( ) . map ( |mut pixel| {
142+ pixel. values = transform. apply ( pixel) ;
143+ pixel
144+ } ) {
145+ let pixel_index = row * self . width + column;
146+ image[ 3 * pixel_index..3 * ( pixel_index + 1 ) ] . copy_from_slice ( & values) ;
147+ }
148+
149+ Image {
150+ channels : 3 ,
151+ data : image,
152+ width : self . width ,
153+ height : self . height ,
154+ transform : self . transform ,
155+ }
156+ }
157+ }
158+
159+ impl Image < u16 > {
160+ pub fn apply ( mut self , mut transform : impl PixelTransform ) -> Image < u16 > {
161+ for ( index, values) in self . data . chunks_exact_mut ( 3 ) . enumerate ( ) {
162+ let pixel = Pixel {
163+ values : values. try_into ( ) . unwrap ( ) ,
164+ row : index / self . width ,
165+ column : index % self . width ,
166+ } ;
167+ values. copy_from_slice ( & transform. apply ( pixel) ) ;
168+ }
169+
170+ self
171+ }
172+
173+ pub fn transform_and_apply ( self , mut transform : impl PixelTransform ) -> Image < u16 > {
174+ let mut image = vec ! [ 0 ; self . width * self . height * 3 ] ;
175+ let ( width, height, iter) = self . transform_iter ( ) ;
176+ for Pixel { values, row, column } in iter. map ( |mut pixel| {
177+ pixel. values = transform. apply ( pixel) ;
178+ pixel
179+ } ) {
180+ let pixel_index = row * width + column;
181+ image[ 3 * pixel_index..3 * ( pixel_index + 1 ) ] . copy_from_slice ( & values) ;
182+ }
183+
184+ Image {
185+ channels : 3 ,
186+ data : image,
187+ width,
188+ height,
189+ transform : Transform :: Horizontal ,
190+ }
191+ }
112192}
113193
114194#[ derive( Error , Debug ) ]
0 commit comments