1
+ use std:: collections:: HashMap ;
2
+ use std:: fmt:: Debug ;
1
3
use std:: io:: { Cursor , Read } ;
2
4
3
5
use bytes:: Bytes ;
@@ -7,47 +9,138 @@ use tiff::{TiffError, TiffUnsupportedError};
7
9
8
10
use crate :: error:: Result ;
9
11
12
+ /// A registry of decoders.
13
+ #[ derive( Debug ) ]
14
+ pub struct DecoderRegistry ( HashMap < CompressionMethod , Box < dyn Decoder > > ) ;
15
+
16
+ impl DecoderRegistry {
17
+ /// Create a new decoder registry with no decoders registered
18
+ pub fn new ( ) -> Self {
19
+ Self ( HashMap :: new ( ) )
20
+ }
21
+ }
22
+
23
+ impl AsRef < HashMap < CompressionMethod , Box < dyn Decoder > > > for DecoderRegistry {
24
+ fn as_ref ( & self ) -> & HashMap < CompressionMethod , Box < dyn Decoder > > {
25
+ & self . 0
26
+ }
27
+ }
28
+
29
+ impl AsMut < HashMap < CompressionMethod , Box < dyn Decoder > > > for DecoderRegistry {
30
+ fn as_mut ( & mut self ) -> & mut HashMap < CompressionMethod , Box < dyn Decoder > > {
31
+ & mut self . 0
32
+ }
33
+ }
34
+
35
+ impl Default for DecoderRegistry {
36
+ fn default ( ) -> Self {
37
+ let mut registry = HashMap :: with_capacity ( 5 ) ;
38
+ registry. insert ( CompressionMethod :: None , Box :: new ( UncompressedDecoder ) as _ ) ;
39
+ registry. insert ( CompressionMethod :: Deflate , Box :: new ( DeflateDecoder ) as _ ) ;
40
+ registry. insert ( CompressionMethod :: OldDeflate , Box :: new ( DeflateDecoder ) as _ ) ;
41
+ registry. insert ( CompressionMethod :: LZW , Box :: new ( LZWDecoder ) as _ ) ;
42
+ registry. insert ( CompressionMethod :: ModernJPEG , Box :: new ( JPEGDecoder ) as _ ) ;
43
+ Self ( registry)
44
+ }
45
+ }
46
+
47
+ /// A trait to decode a TIFF tile.
48
+ pub trait Decoder : Debug + Send + Sync {
49
+ fn decode_tile (
50
+ & self ,
51
+ buffer : Bytes ,
52
+ photometric_interpretation : PhotometricInterpretation ,
53
+ jpeg_tables : Option < & [ u8 ] > ,
54
+ ) -> Result < Bytes > ;
55
+ }
56
+
57
+ #[ derive( Debug , Clone ) ]
58
+ pub struct DeflateDecoder ;
59
+
60
+ impl Decoder for DeflateDecoder {
61
+ fn decode_tile (
62
+ & self ,
63
+ buffer : Bytes ,
64
+ _photometric_interpretation : PhotometricInterpretation ,
65
+ _jpeg_tables : Option < & [ u8 ] > ,
66
+ ) -> Result < Bytes > {
67
+ let mut decoder = ZlibDecoder :: new ( Cursor :: new ( buffer) ) ;
68
+ let mut buf = Vec :: new ( ) ;
69
+ decoder. read_to_end ( & mut buf) ?;
70
+ Ok ( buf. into ( ) )
71
+ }
72
+ }
73
+
74
+ #[ derive( Debug , Clone ) ]
75
+ pub struct JPEGDecoder ;
76
+
77
+ impl Decoder for JPEGDecoder {
78
+ fn decode_tile (
79
+ & self ,
80
+ buffer : Bytes ,
81
+ photometric_interpretation : PhotometricInterpretation ,
82
+ jpeg_tables : Option < & [ u8 ] > ,
83
+ ) -> Result < Bytes > {
84
+ decode_modern_jpeg ( buffer, photometric_interpretation, jpeg_tables)
85
+ }
86
+ }
87
+
88
+ #[ derive( Debug , Clone ) ]
89
+ pub struct LZWDecoder ;
90
+
91
+ impl Decoder for LZWDecoder {
92
+ fn decode_tile (
93
+ & self ,
94
+ buffer : Bytes ,
95
+ _photometric_interpretation : PhotometricInterpretation ,
96
+ _jpeg_tables : Option < & [ u8 ] > ,
97
+ ) -> Result < Bytes > {
98
+ // https://github.com/image-rs/image-tiff/blob/90ae5b8e54356a35e266fb24e969aafbcb26e990/src/decoder/stream.rs#L147
99
+ let mut decoder = weezl:: decode:: Decoder :: with_tiff_size_switch ( weezl:: BitOrder :: Msb , 8 ) ;
100
+ let decoded = decoder. decode ( & buffer) . expect ( "failed to decode LZW data" ) ;
101
+ Ok ( decoded. into ( ) )
102
+ }
103
+ }
104
+
105
+ #[ derive( Debug , Clone ) ]
106
+ pub struct UncompressedDecoder ;
107
+
108
+ impl Decoder for UncompressedDecoder {
109
+ fn decode_tile (
110
+ & self ,
111
+ buffer : Bytes ,
112
+ _photometric_interpretation : PhotometricInterpretation ,
113
+ _jpeg_tables : Option < & [ u8 ] > ,
114
+ ) -> Result < Bytes > {
115
+ Ok ( buffer)
116
+ }
117
+ }
118
+
10
119
// https://github.com/image-rs/image-tiff/blob/3bfb43e83e31b0da476832067ada68a82b378b7b/src/decoder/image.rs#L370
11
120
pub ( crate ) fn decode_tile (
12
121
buf : Bytes ,
13
122
photometric_interpretation : PhotometricInterpretation ,
14
123
compression_method : CompressionMethod ,
15
124
// compressed_length: u64,
16
- jpeg_tables : Option < & Vec < u8 > > ,
125
+ jpeg_tables : Option < & [ u8 ] > ,
126
+ decoder_registry : & DecoderRegistry ,
17
127
) -> Result < Bytes > {
18
- match compression_method {
19
- CompressionMethod :: None => Ok ( buf) ,
20
- CompressionMethod :: LZW => decode_lzw ( buf) ,
21
- CompressionMethod :: Deflate | CompressionMethod :: OldDeflate => decode_deflate ( buf) ,
22
- CompressionMethod :: ModernJPEG => {
23
- decode_modern_jpeg ( buf, photometric_interpretation, jpeg_tables)
24
- }
25
- method => Err ( TiffError :: UnsupportedError (
26
- TiffUnsupportedError :: UnsupportedCompressionMethod ( method) ,
27
- )
28
- . into ( ) ) ,
29
- }
30
- }
31
-
32
- fn decode_lzw ( buf : Bytes ) -> Result < Bytes > {
33
- // https://github.com/image-rs/image-tiff/blob/90ae5b8e54356a35e266fb24e969aafbcb26e990/src/decoder/stream.rs#L147
34
- let mut decoder = weezl:: decode:: Decoder :: with_tiff_size_switch ( weezl:: BitOrder :: Msb , 8 ) ;
35
- let decoded = decoder. decode ( & buf) . expect ( "failed to decode LZW data" ) ;
36
- Ok ( decoded. into ( ) )
37
- }
128
+ let decoder =
129
+ decoder_registry
130
+ . 0
131
+ . get ( & compression_method)
132
+ . ok_or ( TiffError :: UnsupportedError (
133
+ TiffUnsupportedError :: UnsupportedCompressionMethod ( compression_method) ,
134
+ ) ) ?;
38
135
39
- fn decode_deflate ( buf : Bytes ) -> Result < Bytes > {
40
- let mut decoder = ZlibDecoder :: new ( Cursor :: new ( buf) ) ;
41
- let mut buf = Vec :: new ( ) ;
42
- decoder. read_to_end ( & mut buf) ?;
43
- Ok ( buf. into ( ) )
136
+ decoder. decode_tile ( buf, photometric_interpretation, jpeg_tables)
44
137
}
45
138
46
139
// https://github.com/image-rs/image-tiff/blob/3bfb43e83e31b0da476832067ada68a82b378b7b/src/decoder/image.rs#L389-L450
47
140
fn decode_modern_jpeg (
48
141
buf : Bytes ,
49
142
photometric_interpretation : PhotometricInterpretation ,
50
- jpeg_tables : Option < & Vec < u8 > > ,
143
+ jpeg_tables : Option < & [ u8 ] > ,
51
144
) -> Result < Bytes > {
52
145
// Construct new jpeg_reader wrapping a SmartReader.
53
146
//
@@ -76,13 +169,9 @@ fn decode_modern_jpeg(
76
169
77
170
match photometric_interpretation {
78
171
PhotometricInterpretation :: RGB => decoder. set_color_transform ( jpeg:: ColorTransform :: RGB ) ,
79
- PhotometricInterpretation :: WhiteIsZero => {
80
- decoder. set_color_transform ( jpeg:: ColorTransform :: None )
81
- }
82
- PhotometricInterpretation :: BlackIsZero => {
83
- decoder. set_color_transform ( jpeg:: ColorTransform :: None )
84
- }
85
- PhotometricInterpretation :: TransparencyMask => {
172
+ PhotometricInterpretation :: WhiteIsZero
173
+ | PhotometricInterpretation :: BlackIsZero
174
+ | PhotometricInterpretation :: TransparencyMask => {
86
175
decoder. set_color_transform ( jpeg:: ColorTransform :: None )
87
176
}
88
177
PhotometricInterpretation :: CMYK => decoder. set_color_transform ( jpeg:: ColorTransform :: CMYK ) ,
0 commit comments