11use crate :: {
22 impl_read_for_datatype, impl_read_slice,
33 jpeg:: grammar:: {
4- Component , EncodingProcess , HuffmanTable , Jpeg , Marker , Precision , QuantizationTable ,
5- StartOfFrame , StartOfScan , JFIF ,
4+ ApplicationHeader , Component , EncodingProcess , HuffmanTable , Jpeg , Marker , Precision ,
5+ QuantizationTable , StartOfFrame , StartOfScan , JFIF ,
66 } ,
77} ;
88
99use anyhow:: { anyhow, ensure, Result } ;
10- use std:: ops:: { Range , RangeInclusive } ;
10+ use std:: ops:: RangeInclusive ;
1111
1212#[ derive( Debug ) ]
1313pub struct JpegDecoder < ' a > {
@@ -28,9 +28,10 @@ impl<'a> JpegDecoder<'a> {
2828 todo ! ( ) ;
2929 }
3030
31- fn parse_jfif ( & mut self ) -> Result < JFIF > {
31+ fn parse_jfif ( & mut self ) -> Result < JFIF < ' a > > {
3232 ensure ! ( self . read_marker( ) ? == 0xFFD8 ) ;
3333
34+ let mut application_header = None ;
3435 let mut quantization_tables = Vec :: with_capacity ( 4 ) ;
3536 let mut huffman_tables = Vec :: new ( ) ;
3637 let mut start_of_frame = None ;
@@ -40,7 +41,7 @@ impl<'a> JpegDecoder<'a> {
4041 loop {
4142 match self . read_marker ( ) ? {
4243 0xFFE0 => {
43- self . parse_application_header ( ) ?;
44+ application_header = Some ( self . parse_application_header ( ) ?) ;
4445 }
4546 0xFFDB => {
4647 quantization_tables. push ( self . parse_quantization_table ( ) ?) ;
@@ -55,7 +56,10 @@ impl<'a> JpegDecoder<'a> {
5556
5657 break ;
5758 }
58- start_of_frame_marker if ( start_of_frame_marker as u8 & 0xF0 ) == 0xC0 => {
59+ start_of_frame_marker
60+ if start_of_frame_marker >> 8 == 0xFF
61+ && ( start_of_frame_marker as u8 & 0xF0 ) == 0xC0 =>
62+ {
5963 ensure ! ( start_of_frame. is_none( ) ) ;
6064 start_of_frame = Some ( self . parse_start_of_frame ( start_of_frame_marker as u8 ) ?) ;
6165 }
@@ -66,6 +70,8 @@ impl<'a> JpegDecoder<'a> {
6670 ensure ! ( self . read_marker( ) ? == 0xFFD9 ) ;
6771
6872 Ok ( JFIF {
73+ application_header : application_header
74+ . ok_or_else ( || anyhow ! ( "expected application header" ) ) ?,
6975 quantization_tables,
7076 huffman_tables : {
7177 ensure ! ( huffman_tables. len( ) == 4 ) ;
@@ -77,15 +83,22 @@ impl<'a> JpegDecoder<'a> {
7783 } )
7884 }
7985
80- fn parse_application_header ( & mut self ) -> Result < ( ) > {
86+ fn parse_application_header ( & mut self ) -> Result < ApplicationHeader > {
8187 let offset = self . cursor ;
82- let length = self . read_u16 ( ) ?;
88+ let length = self . read_u16 ( ) ? as usize ;
8389
8490 ensure ! ( self . read_slice( 5 ) ? == b"JFIF\0 " ) ;
8591
86- self . cursor = offset + length as usize ;
92+ let app_header = ApplicationHeader {
93+ version : ( self . read_u8 ( ) ?, self . read_u8 ( ) ?) ,
94+ unit : self . read_u8 ( ) ?,
95+ density : ( self . read_u16 ( ) ?, self . read_u16 ( ) ?) ,
96+ thumbnail : ( self . read_u8 ( ) ?, self . read_u8 ( ) ?) ,
97+ } ;
8798
88- Ok ( ( ) )
99+ ensure ! ( self . cursor == offset + length) ;
100+
101+ Ok ( app_header)
89102 }
90103
91104 fn parse_quantization_table ( & mut self ) -> Result < QuantizationTable > {
@@ -148,28 +161,19 @@ impl<'a> JpegDecoder<'a> {
148161 let length = self . read_u16 ( ) ? as usize ;
149162
150163 let flag = self . read_u8 ( ) ?;
164+ let code_lengths = self . read_fixed_array :: < 16 , _ > ( Self :: read_u8) ?;
165+ let num_values = code_lengths. iter ( ) . sum :: < u8 > ( ) ;
166+ let values = self . read_vec ( num_values as usize , Self :: read_u8) ?;
151167
152- let huffman_table = HuffmanTable {
168+ let ht = HuffmanTable {
153169 flag,
154- code_lengths : {
155- let code_lengths = Range {
156- start : self . cursor ,
157- end : self . cursor + 16 ,
158- } ;
159-
160- self . cursor += 16 ;
161-
162- code_lengths
163- } ,
164- symbols : Range {
165- start : self . cursor ,
166- end : offset + length,
167- } ,
170+ code_lengths,
171+ values,
168172 } ;
169173
170- self . cursor = offset + length;
174+ ensure ! ( self . cursor == offset + length) ;
171175
172- Ok ( huffman_table )
176+ Ok ( ht )
173177 }
174178
175179 fn parse_start_of_scan ( & mut self ) -> Result < StartOfScan > {
@@ -192,35 +196,37 @@ impl<'a> JpegDecoder<'a> {
192196 Ok ( start_of_scan)
193197 }
194198
195- fn parse_image_data ( & mut self ) -> Result < Range < usize > > {
196- let range = Range {
197- start : self . cursor ,
198- end : {
199- while self . peek_slice ( 2 ) ? != [ 0xFF , 0xD9 ] {
200- self . cursor += 1 ;
201- }
199+ fn parse_image_data ( & mut self ) -> Result < & ' a [ u8 ] > {
200+ let len = self . count_until ( |this| Ok ( this. peek_slice ( 2 ) ? != [ 0xFF , 0xD9 ] ) ) ?;
202201
203- self . cursor
204- } ,
205- } ;
206-
207- Ok ( range)
202+ self . read_slice ( len)
208203 }
209204
210205 impl_read_for_datatype ! ( read_u8, u8 ) ;
211206 impl_read_for_datatype ! ( read_u16, u16 ) ;
212207 impl_read_for_datatype ! ( read_marker, Marker ) ;
213208 impl_read_slice ! ( ) ;
209+
210+ /// counts the number of bytes until the reader reaches term function
211+ fn count_until ( & self , term_fn : impl Fn ( & Self ) -> Result < bool > ) -> Result < usize > {
212+ let mut len = 0 ;
213+
214+ while !term_fn ( self ) ? {
215+ len += 1 ;
216+ }
217+
218+ Ok ( len)
219+ }
214220}
215221
216- // #[cfg(test)]
217- // mod tests {
218- // use super::*;
222+ #[ cfg( test) ]
223+ mod tests {
224+ use super :: * ;
219225
220- // #[test]
221- // fn test_decode_taxi_zone_map_manhattan() {
222- // let data = std::fs::read("./tests/taxi_zone_map_manhattan.jpg").unwrap();
226+ #[ test]
227+ fn test_decode_taxi_zone_map_manhattan ( ) {
228+ let data = std:: fs:: read ( "./tests/taxi_zone_map_manhattan.jpg" ) . unwrap ( ) ;
223229
224- // let _ = JpegDecoder::new(&data).decode().unwrap();
225- // }
226- // }
230+ let _ = JpegDecoder :: new ( & data) . decode ( ) . unwrap ( ) ;
231+ }
232+ }
0 commit comments