dicom_encoding/decode/
basic.rs

1//! This module provides implementations for primitive decoders of data, which
2//! may be in either Little Endian or Big Endian.
3
4use super::BasicDecode;
5use byteordered::{ByteOrdered, Endianness};
6use std::io::Read;
7
8type Result<T> = std::io::Result<T>;
9
10/// A basic decoder of DICOM primitive elements in little endian.
11#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
12pub struct LittleEndianBasicDecoder;
13
14impl BasicDecode for LittleEndianBasicDecoder {
15    fn endianness(&self) -> Endianness {
16        Endianness::Little
17    }
18
19    fn decode_us<S>(&self, source: S) -> Result<u16>
20    where
21        S: Read,
22    {
23        ByteOrdered::le(source).read_u16().map_err(Into::into)
24    }
25
26    fn decode_us_into<S>(&self, source: S, target: &mut [u16]) -> Result<()>
27    where
28        S: Read,
29    {
30        ByteOrdered::le(source)
31            .read_u16_into(target)
32            .map_err(Into::into)
33    }
34
35    fn decode_ul<S>(&self, source: S) -> Result<u32>
36    where
37        S: Read,
38    {
39        ByteOrdered::le(source).read_u32().map_err(Into::into)
40    }
41
42    fn decode_ul_into<S>(&self, source: S, target: &mut [u32]) -> Result<()>
43    where
44        S: Read,
45    {
46        ByteOrdered::le(source)
47            .read_u32_into(target)
48            .map_err(Into::into)
49    }
50
51    fn decode_uv<S>(&self, source: S) -> Result<u64>
52    where
53        S: Read,
54    {
55        ByteOrdered::le(source).read_u64().map_err(Into::into)
56    }
57
58    fn decode_uv_into<S>(&self, source: S, target: &mut [u64]) -> Result<()>
59    where
60        S: Read,
61    {
62        ByteOrdered::le(source)
63            .read_u64_into(target)
64            .map_err(Into::into)
65    }
66
67    fn decode_ss<S>(&self, source: S) -> Result<i16>
68    where
69        S: Read,
70    {
71        ByteOrdered::le(source).read_i16().map_err(Into::into)
72    }
73
74    fn decode_ss_into<S>(&self, source: S, target: &mut [i16]) -> Result<()>
75    where
76        S: Read,
77    {
78        ByteOrdered::le(source)
79            .read_i16_into(target)
80            .map_err(Into::into)
81    }
82
83    fn decode_sl<S>(&self, source: S) -> Result<i32>
84    where
85        S: Read,
86    {
87        ByteOrdered::le(source).read_i32().map_err(Into::into)
88    }
89
90    fn decode_sl_into<S>(&self, source: S, target: &mut [i32]) -> Result<()>
91    where
92        S: Read,
93    {
94        ByteOrdered::le(source)
95            .read_i32_into(target)
96            .map_err(Into::into)
97    }
98
99    fn decode_sv<S>(&self, source: S) -> Result<i64>
100    where
101        S: Read,
102    {
103        ByteOrdered::le(source).read_i64().map_err(Into::into)
104    }
105
106    fn decode_sv_into<S>(&self, source: S, target: &mut [i64]) -> Result<()>
107    where
108        S: Read,
109    {
110        ByteOrdered::le(source)
111            .read_i64_into(target)
112            .map_err(Into::into)
113    }
114
115    fn decode_fl<S>(&self, source: S) -> Result<f32>
116    where
117        S: Read,
118    {
119        ByteOrdered::le(source).read_f32().map_err(Into::into)
120    }
121
122    fn decode_fl_into<S>(&self, source: S, target: &mut [f32]) -> Result<()>
123    where
124        S: Read,
125    {
126        ByteOrdered::le(source)
127            .read_f32_into(target)
128            .map_err(Into::into)
129    }
130
131    fn decode_fd<S>(&self, source: S) -> Result<f64>
132    where
133        S: Read,
134    {
135        ByteOrdered::le(source).read_f64().map_err(Into::into)
136    }
137
138    fn decode_fd_into<S>(&self, source: S, target: &mut [f64]) -> Result<()>
139    where
140        S: Read,
141    {
142        ByteOrdered::le(source)
143            .read_f64_into(target)
144            .map_err(Into::into)
145    }
146}
147
148/// A basic decoder of DICOM primitive elements in big endian.
149#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
150pub struct BigEndianBasicDecoder;
151
152impl BasicDecode for BigEndianBasicDecoder {
153    fn endianness(&self) -> Endianness {
154        Endianness::Big
155    }
156
157    fn decode_us<S>(&self, source: S) -> Result<u16>
158    where
159        S: Read,
160    {
161        ByteOrdered::be(source).read_u16().map_err(Into::into)
162    }
163
164    fn decode_us_into<S>(&self, source: S, target: &mut [u16]) -> Result<()>
165    where
166        S: Read,
167    {
168        ByteOrdered::be(source)
169            .read_u16_into(target)
170            .map_err(Into::into)
171    }
172
173    fn decode_ul<S>(&self, source: S) -> Result<u32>
174    where
175        S: Read,
176    {
177        ByteOrdered::be(source).read_u32().map_err(Into::into)
178    }
179
180    fn decode_ul_into<S>(&self, source: S, target: &mut [u32]) -> Result<()>
181    where
182        S: Read,
183    {
184        ByteOrdered::be(source)
185            .read_u32_into(target)
186            .map_err(Into::into)
187    }
188
189    fn decode_uv<S>(&self, source: S) -> Result<u64>
190    where
191        S: Read,
192    {
193        ByteOrdered::be(source).read_u64().map_err(Into::into)
194    }
195
196    fn decode_uv_into<S>(&self, source: S, target: &mut [u64]) -> Result<()>
197    where
198        S: Read,
199    {
200        ByteOrdered::be(source)
201            .read_u64_into(target)
202            .map_err(Into::into)
203    }
204
205    fn decode_ss<S>(&self, source: S) -> Result<i16>
206    where
207        S: Read,
208    {
209        ByteOrdered::be(source).read_i16().map_err(Into::into)
210    }
211
212    fn decode_ss_into<S>(&self, source: S, target: &mut [i16]) -> Result<()>
213    where
214        S: Read,
215    {
216        ByteOrdered::be(source)
217            .read_i16_into(target)
218            .map_err(Into::into)
219    }
220
221    fn decode_sl<S>(&self, source: S) -> Result<i32>
222    where
223        S: Read,
224    {
225        ByteOrdered::be(source).read_i32().map_err(Into::into)
226    }
227
228    fn decode_sl_into<S>(&self, source: S, target: &mut [i32]) -> Result<()>
229    where
230        S: Read,
231    {
232        ByteOrdered::be(source)
233            .read_i32_into(target)
234            .map_err(Into::into)
235    }
236
237    fn decode_sv<S>(&self, source: S) -> Result<i64>
238    where
239        S: Read,
240    {
241        ByteOrdered::be(source).read_i64().map_err(Into::into)
242    }
243
244    fn decode_sv_into<S>(&self, source: S, target: &mut [i64]) -> Result<()>
245    where
246        S: Read,
247    {
248        ByteOrdered::be(source)
249            .read_i64_into(target)
250            .map_err(Into::into)
251    }
252
253    fn decode_fl<S>(&self, source: S) -> Result<f32>
254    where
255        S: Read,
256    {
257        ByteOrdered::be(source).read_f32().map_err(Into::into)
258    }
259
260    fn decode_fl_into<S>(&self, source: S, target: &mut [f32]) -> Result<()>
261    where
262        S: Read,
263    {
264        ByteOrdered::be(source)
265            .read_f32_into(target)
266            .map_err(Into::into)
267    }
268
269    fn decode_fd<S>(&self, source: S) -> Result<f64>
270    where
271        S: Read,
272    {
273        ByteOrdered::be(source).read_f64().map_err(Into::into)
274    }
275
276    fn decode_fd_into<S>(&self, source: S, target: &mut [f64]) -> Result<()>
277    where
278        S: Read,
279    {
280        ByteOrdered::be(source)
281            .read_f64_into(target)
282            .map_err(Into::into)
283    }
284}
285
286/// A basic decoder with support for both Little Endian an Big Endian
287/// encoding, decided at run-time. Since only two values are possible,
288/// this enum may become more efficient than the use of a trait object.
289#[derive(Debug, Clone, PartialEq)]
290pub enum BasicDecoder {
291    /// Decode in Little Endian
292    LE(LittleEndianBasicDecoder),
293    /// Decode in Big Endian
294    BE(BigEndianBasicDecoder),
295}
296
297impl BasicDecoder {
298    /// Create a basic decoder for the given byte order.
299    pub fn new(endianness: Endianness) -> Self {
300        match endianness {
301            Endianness::Little => LE(LittleEndianBasicDecoder),
302            Endianness::Big => BE(BigEndianBasicDecoder),
303        }
304    }
305}
306
307use self::BasicDecoder::{BE, LE};
308
309impl From<Endianness> for BasicDecoder {
310    fn from(endianness: Endianness) -> Self {
311        BasicDecoder::new(endianness)
312    }
313}
314
315macro_rules! for_both {
316    ($s: expr, |$e: ident| $f: expr) => {
317        match *$s {
318            LE(ref $e) => $f,
319            BE(ref $e) => $f,
320        }
321    };
322}
323
324impl BasicDecode for BasicDecoder {
325    fn endianness(&self) -> Endianness {
326        match *self {
327            LE(_) => Endianness::Little,
328            BE(_) => Endianness::Big,
329        }
330    }
331
332    fn decode_us<S>(&self, source: S) -> Result<u16>
333    where
334        S: Read,
335    {
336        for_both!(self, |e| e.decode_us(source))
337    }
338
339    fn decode_us_into<S>(&self, source: S, target: &mut [u16]) -> Result<()>
340    where
341        S: Read,
342    {
343        for_both!(self, |e| e.decode_us_into(source, target))
344    }
345
346    fn decode_ul<S>(&self, source: S) -> Result<u32>
347    where
348        S: Read,
349    {
350        for_both!(self, |e| e.decode_ul(source))
351    }
352
353    fn decode_ul_into<S>(&self, source: S, target: &mut [u32]) -> Result<()>
354    where
355        S: Read,
356    {
357        for_both!(self, |e| e.decode_ul_into(source, target))
358    }
359
360    fn decode_uv<S>(&self, source: S) -> Result<u64>
361    where
362        S: Read,
363    {
364        for_both!(self, |e| e.decode_uv(source))
365    }
366
367    fn decode_uv_into<S>(&self, source: S, target: &mut [u64]) -> Result<()>
368    where
369        S: Read,
370    {
371        for_both!(self, |e| e.decode_uv_into(source, target))
372    }
373
374    fn decode_ss<S>(&self, source: S) -> Result<i16>
375    where
376        S: Read,
377    {
378        for_both!(self, |e| e.decode_ss(source))
379    }
380
381    fn decode_ss_into<S>(&self, source: S, target: &mut [i16]) -> Result<()>
382    where
383        S: Read,
384    {
385        for_both!(self, |e| e.decode_ss_into(source, target))
386    }
387
388    fn decode_sl<S>(&self, source: S) -> Result<i32>
389    where
390        S: Read,
391    {
392        for_both!(self, |e| e.decode_sl(source))
393    }
394
395    fn decode_sl_into<S>(&self, source: S, target: &mut [i32]) -> Result<()>
396    where
397        S: Read,
398    {
399        for_both!(self, |e| e.decode_sl_into(source, target))
400    }
401
402    fn decode_sv<S>(&self, source: S) -> Result<i64>
403    where
404        S: Read,
405    {
406        for_both!(self, |e| e.decode_sv(source))
407    }
408
409    fn decode_sv_into<S>(&self, source: S, target: &mut [i64]) -> Result<()>
410    where
411        S: Read,
412    {
413        for_both!(self, |e| e.decode_sv_into(source, target))
414    }
415
416    fn decode_fl<S>(&self, source: S) -> Result<f32>
417    where
418        S: Read,
419    {
420        for_both!(self, |e| e.decode_fl(source))
421    }
422
423    fn decode_fl_into<S>(&self, source: S, target: &mut [f32]) -> Result<()>
424    where
425        S: Read,
426    {
427        for_both!(self, |e| e.decode_fl_into(source, target))
428    }
429
430    fn decode_fd<S>(&self, source: S) -> Result<f64>
431    where
432        S: Read,
433    {
434        for_both!(self, |e| e.decode_fd(source))
435    }
436
437    fn decode_fd_into<S>(&self, source: S, target: &mut [f64]) -> Result<()>
438    where
439        S: Read,
440    {
441        for_both!(self, |e| e.decode_fd_into(source, target))
442    }
443}
444
445#[cfg(test)]
446mod tests {
447
448    use super::*;
449
450    #[test]
451    fn test_read_integers() {
452        let data: &[u8] = &[0xC3, 0x3C, 0x33, 0xCC, 0x55, 0xAA, 0x55, 0xAA];
453
454        let le = LittleEndianBasicDecoder;
455        let be = BigEndianBasicDecoder;
456
457        assert_eq!(le.decode_us(data).unwrap(), 0x3CC3);
458        assert_eq!(be.decode_us(data).unwrap(), 0xC33C);
459        assert_eq!(le.decode_ul(data).unwrap(), 0xCC333CC3);
460        assert_eq!(be.decode_ul(data).unwrap(), 0xC33C33CC);
461        assert_eq!(le.decode_uv(data).unwrap(), 0xAA55AA55_CC333CC3);
462        assert_eq!(be.decode_uv(data).unwrap(), 0xC33C33CC_55AA55AA);
463
464        let le = BasicDecoder::new(Endianness::Little);
465        let be = BasicDecoder::new(Endianness::Big);
466
467        assert_eq!(le.decode_us(data).unwrap(), 0x3CC3);
468        assert_eq!(be.decode_us(data).unwrap(), 0xC33C);
469        assert_eq!(le.decode_ul(data).unwrap(), 0xCC333CC3);
470        assert_eq!(be.decode_ul(data).unwrap(), 0xC33C33CC);
471        assert_eq!(le.decode_uv(data).unwrap(), 0xAA55AA55_CC333CC3);
472        assert_eq!(be.decode_uv(data).unwrap(), 0xC33C33CC_55AA55AA);
473    }
474
475    #[test]
476    fn test_read_integers_into() {
477        let data: &[u8] = &[0xC3, 0x3C, 0x33, 0xCC, 0x55, 0xAA, 0x55, 0xAA];
478
479        let le = LittleEndianBasicDecoder;
480        let be = BigEndianBasicDecoder;
481
482        let mut out_le = [0; 4];
483        le.decode_us_into(data, &mut out_le).unwrap();
484        assert_eq!(out_le, [0x3CC3, 0xCC33, 0xAA55, 0xAA55]);
485
486        let mut out_be = [0; 4];
487        be.decode_us_into(data, &mut out_be).unwrap();
488        assert_eq!(out_be, [0xC33C, 0x33CC, 0x55AA, 0x55AA]);
489
490        let mut out_le = [0; 2];
491        le.decode_ul_into(data, &mut out_le).unwrap();
492        assert_eq!(out_le, [0xCC33_3CC3, 0xAA55_AA55]);
493
494        let mut out_be = [0; 2];
495        be.decode_ul_into(data, &mut out_be).unwrap();
496        assert_eq!(out_be, [0xC33C_33CC, 0x55AA_55AA]);
497
498        let le = BasicDecoder::new(Endianness::Little);
499        let be = BasicDecoder::new(Endianness::Big);
500
501        let mut out_le = [0; 4];
502        le.decode_us_into(data, &mut out_le).unwrap();
503        assert_eq!(out_le, [0x3CC3, 0xCC33, 0xAA55, 0xAA55]);
504
505        let mut out_be = [0; 4];
506        be.decode_us_into(data, &mut out_be).unwrap();
507        assert_eq!(out_be, [0xC33C, 0x33CC, 0x55AA, 0x55AA]);
508
509        let mut out_le = [0; 2];
510        le.decode_ul_into(data, &mut out_le).unwrap();
511        assert_eq!(out_le, [0xCC33_3CC3, 0xAA55_AA55]);
512
513        let mut out_be = [0; 2];
514        be.decode_ul_into(data, &mut out_be).unwrap();
515        assert_eq!(out_be, [0xC33C_33CC, 0x55AA_55AA]);
516    }
517}