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