@@ -18,6 +18,9 @@ use worker::{RowData, PlatformWorker, Worker};
18
18
19
19
pub const MAX_COMPONENTS : usize = 4 ;
20
20
21
+ mod lossless;
22
+ use self :: lossless:: compute_image_lossless;
23
+
21
24
static UNZIGZAG : [ u8 ; 64 ] = [
22
25
0 , 1 , 8 , 16 , 9 , 2 , 3 , 10 ,
23
26
17 , 24 , 32 , 25 , 18 , 11 , 4 , 5 ,
@@ -34,6 +37,8 @@ static UNZIGZAG: [u8; 64] = [
34
37
pub enum PixelFormat {
35
38
/// Luminance (grayscale), 8 bits
36
39
L8 ,
40
+ /// Luminance (grayscale), 16 bits
41
+ L16 ,
37
42
/// RGB, 8 bits per channel
38
43
RGB24 ,
39
44
/// CMYK, 8 bits per channel
@@ -45,6 +50,7 @@ impl PixelFormat {
45
50
pub fn pixel_bytes ( & self ) -> usize {
46
51
match self {
47
52
PixelFormat :: L8 => 1 ,
53
+ PixelFormat :: L16 => 2 ,
48
54
PixelFormat :: RGB24 => 3 ,
49
55
PixelFormat :: CMYK32 => 4 ,
50
56
}
@@ -60,6 +66,8 @@ pub struct ImageInfo {
60
66
pub height : u16 ,
61
67
/// The pixel format of the image.
62
68
pub pixel_format : PixelFormat ,
69
+ /// The coding process of the image.
70
+ pub coding_process : CodingProcess ,
63
71
}
64
72
65
73
/// JPEG decoder
@@ -114,7 +122,11 @@ impl<R: Read> Decoder<R> {
114
122
match self . frame {
115
123
Some ( ref frame) => {
116
124
let pixel_format = match frame. components . len ( ) {
117
- 1 => PixelFormat :: L8 ,
125
+ 1 => match frame. precision {
126
+ 8 => PixelFormat :: L8 ,
127
+ 16 => PixelFormat :: L16 ,
128
+ _ => panic ! ( )
129
+ } ,
118
130
3 => PixelFormat :: RGB24 ,
119
131
4 => PixelFormat :: CMYK32 ,
120
132
_ => panic ! ( ) ,
@@ -124,6 +136,7 @@ impl<R: Read> Decoder<R> {
124
136
width : frame. output_size . width ,
125
137
height : frame. output_size . height ,
126
138
pixel_format : pixel_format,
139
+ coding_process : frame. coding_process ,
127
140
} )
128
141
} ,
129
142
None => None ,
@@ -212,7 +225,8 @@ impl<R: Read> Decoder<R> {
212
225
let mut pending_marker = None ;
213
226
let mut worker = None ;
214
227
let mut scans_processed = 0 ;
215
- let mut planes = vec ! [ Vec :: new( ) ; self . frame. as_ref( ) . map_or( 0 , |frame| frame. components. len( ) ) ] ;
228
+ let mut planes = vec ! [ Vec :: <u8 >:: new( ) ; self . frame. as_ref( ) . map_or( 0 , |frame| frame. components. len( ) ) ] ;
229
+ let mut planes_u16 = vec ! [ Vec :: <u16 >:: new( ) ; self . frame. as_ref( ) . map_or( 0 , |frame| frame. components. len( ) ) ] ;
216
230
217
231
loop {
218
232
let marker = match pending_marker. take ( ) {
@@ -237,13 +251,13 @@ impl<R: Read> Decoder<R> {
237
251
if frame. is_differential {
238
252
return Err ( Error :: Unsupported ( UnsupportedFeature :: Hierarchical ) ) ;
239
253
}
240
- if frame. coding_process == CodingProcess :: Lossless {
241
- return Err ( Error :: Unsupported ( UnsupportedFeature :: Lossless ) ) ;
242
- }
243
254
if frame. entropy_coding == EntropyCoding :: Arithmetic {
244
255
return Err ( Error :: Unsupported ( UnsupportedFeature :: ArithmeticEntropyCoding ) ) ;
245
256
}
246
- if frame. precision != 8 {
257
+ if frame. precision != 8 && frame. coding_process != CodingProcess :: Lossless {
258
+ return Err ( Error :: Unsupported ( UnsupportedFeature :: SamplePrecision ( frame. precision ) ) ) ;
259
+ }
260
+ if frame. precision != 8 && frame. precision != 16 {
247
261
return Err ( Error :: Unsupported ( UnsupportedFeature :: SamplePrecision ( frame. precision ) ) ) ;
248
262
}
249
263
if component_count != 1 && component_count != 3 && component_count != 4 {
@@ -260,6 +274,7 @@ impl<R: Read> Decoder<R> {
260
274
}
261
275
262
276
planes = vec ! [ Vec :: new( ) ; component_count] ;
277
+ planes_u16 = vec ! [ Vec :: new( ) ; component_count] ;
263
278
} ,
264
279
265
280
// Scan header
@@ -281,46 +296,57 @@ impl<R: Read> Decoder<R> {
281
296
} ) . collect ( ) ;
282
297
}
283
298
284
- // This was previously buggy, so let's explain the log here a bit. When a
285
- // progressive frame is encoded then the coefficients (DC, AC) of each
286
- // component (=color plane) can be split amongst scans. In particular it can
287
- // happen or at least occurs in the wild that a scan contains coefficient 0 of
288
- // all components. If now one but not all components had all other coefficients
289
- // delivered in previous scans then such a scan contains all components but
290
- // completes only some of them! (This is technically NOT permitted for all
291
- // other coefficients as the standard dictates that scans with coefficients
292
- // other than the 0th must only contain ONE component so we would either
293
- // complete it or not. We may want to detect and error in case more component
294
- // are part of a scan than allowed.) What a weird edge case.
295
- //
296
- // But this means we track precisely which components get completed here.
297
- let mut finished = [ false ; MAX_COMPONENTS ] ;
298
-
299
- if scan. successive_approximation_low == 0 {
300
- for ( & i, component_finished) in scan. component_indices . iter ( ) . zip ( & mut finished) {
301
- if self . coefficients_finished [ i] == !0 {
302
- continue ;
303
- }
304
- for j in scan. spectral_selection . clone ( ) {
305
- self . coefficients_finished [ i] |= 1 << j;
306
- }
307
- if self . coefficients_finished [ i] == !0 {
308
- * component_finished = true ;
309
- }
299
+
300
+ if frame. coding_process == CodingProcess :: Lossless {
301
+ let ( marker, data) = self . decode_scan_lossless ( & frame, & scan) ?;
302
+
303
+ for ( i, plane) in data. into_iter ( ) . enumerate ( ) . filter ( |& ( _, ref plane) | !plane. is_empty ( ) ) {
304
+ planes_u16[ i] = plane;
310
305
}
306
+ pending_marker = marker;
311
307
}
308
+ else {
309
+ // This was previously buggy, so let's explain the log here a bit. When a
310
+ // progressive frame is encoded then the coefficients (DC, AC) of each
311
+ // component (=color plane) can be split amongst scans. In particular it can
312
+ // happen or at least occurs in the wild that a scan contains coefficient 0 of
313
+ // all components. If now one but not all components had all other coefficients
314
+ // delivered in previous scans then such a scan contains all components but
315
+ // completes only some of them! (This is technically NOT permitted for all
316
+ // other coefficients as the standard dictates that scans with coefficients
317
+ // other than the 0th must only contain ONE component so we would either
318
+ // complete it or not. We may want to detect and error in case more component
319
+ // are part of a scan than allowed.) What a weird edge case.
320
+ //
321
+ // But this means we track precisely which components get completed here.
322
+ let mut finished = [ false ; MAX_COMPONENTS ] ;
323
+
324
+ if scan. successive_approximation_low == 0 {
325
+ for ( & i, component_finished) in scan. component_indices . iter ( ) . zip ( & mut finished) {
326
+ if self . coefficients_finished [ i] == !0 {
327
+ continue ;
328
+ }
329
+ for j in scan. spectral_selection . clone ( ) {
330
+ self . coefficients_finished [ i] |= 1 << j;
331
+ }
332
+ if self . coefficients_finished [ i] == !0 {
333
+ * component_finished = true ;
334
+ }
335
+ }
336
+ }
312
337
313
- let ( marker, data) = self . decode_scan ( & frame, & scan, worker. as_mut ( ) . unwrap ( ) , & finished) ?;
338
+ let ( marker, data) = self . decode_scan ( & frame, & scan, worker. as_mut ( ) . unwrap ( ) , & finished) ?;
314
339
315
- if let Some ( data) = data {
316
- for ( i, plane) in data. into_iter ( ) . enumerate ( ) . filter ( |& ( _, ref plane) | !plane. is_empty ( ) ) {
317
- if self . coefficients_finished [ i] == !0 {
318
- planes[ i] = plane;
340
+ if let Some ( data) = data {
341
+ for ( i, plane) in data. into_iter ( ) . enumerate ( ) . filter ( |& ( _, ref plane) | !plane. is_empty ( ) ) {
342
+ if self . coefficients_finished [ i] == !0 {
343
+ planes[ i] = plane;
344
+ }
319
345
}
320
346
}
347
+ pending_marker = marker;
321
348
}
322
349
323
- pending_marker = marker;
324
350
scans_processed += 1 ;
325
351
} ,
326
352
@@ -468,7 +494,12 @@ impl<R: Read> Decoder<R> {
468
494
}
469
495
}
470
496
471
- compute_image ( & frame. components , planes, frame. output_size , self . is_jfif , self . color_transform )
497
+ if frame. coding_process == CodingProcess :: Lossless {
498
+ compute_image_lossless ( & frame, planes_u16)
499
+ }
500
+ else {
501
+ compute_image ( & frame. components , planes, frame. output_size , self . is_jfif , self . color_transform )
502
+ }
472
503
}
473
504
474
505
fn read_marker ( & mut self ) -> Result < Marker > {
@@ -967,6 +998,7 @@ fn compute_image(components: &[Component],
967
998
}
968
999
}
969
1000
1001
+
970
1002
#[ cfg( feature="rayon" ) ]
971
1003
fn compute_image_parallel ( components : & [ Component ] ,
972
1004
data : Vec < Vec < u8 > > ,
0 commit comments