dicom_parser/stateful/
decode.rs

1//! Module holding a stateful DICOM data decoding abstraction,
2//! which also supports text decoding.
3
4use crate::util::n_times;
5use dicom_core::dictionary::VirtualVr;
6use dicom_core::header::{DataElementHeader, HasLength, Length, SequenceItemHeader, Tag, VR};
7use dicom_core::value::deserialize::{
8    parse_date_partial, parse_datetime_partial, parse_time_partial,
9};
10use dicom_core::value::PrimitiveValue;
11use dicom_dictionary_std::StandardDataDictionary;
12use dicom_encoding::decode::basic::{BasicDecoder, LittleEndianBasicDecoder};
13use dicom_encoding::decode::explicit_le::ExplicitVRLittleEndianDecoder;
14use dicom_encoding::decode::{BasicDecode, DecodeFrom};
15use dicom_encoding::text::{
16    validate_da, validate_dt, validate_tm, DefaultCharacterSetCodec, SpecificCharacterSet,
17    TextCodec, TextValidationOutcome,
18};
19use dicom_encoding::transfer_syntax::{DynDecoder, TransferSyntax};
20use smallvec::smallvec;
21use snafu::{Backtrace, OptionExt, ResultExt, Snafu};
22use std::io::Read;
23use std::{fmt::Debug, io::Seek, io::SeekFrom};
24
25#[derive(Debug, Snafu)]
26#[non_exhaustive]
27pub enum Error {
28    #[snafu(display("Decoding in transfer syntax {} is unsupported", ts))]
29    UnsupportedTransferSyntax {
30        ts: &'static str,
31        backtrace: Backtrace,
32    },
33
34    #[snafu(display("Unsupported character set {:?}", charset))]
35    UnsupportedCharacterSet {
36        charset: SpecificCharacterSet,
37        backtrace: Backtrace,
38    },
39
40    #[snafu(display("Attempted to read non-primitive value at position {}", position))]
41    NonPrimitiveType { position: u64, backtrace: Backtrace },
42
43    #[snafu(display(
44        "Undefined value length of element tagged {} at position {}",
45        tag,
46        position
47    ))]
48    UndefinedValueLength {
49        tag: Tag,
50        position: u64,
51        backtrace: Backtrace,
52    },
53
54    #[snafu(display("Could not decode element header at position {}", position))]
55    DecodeElementHeader {
56        position: u64,
57        #[snafu(backtrace)]
58        source: dicom_encoding::decode::Error,
59    },
60
61    #[snafu(display("Could not decode element header at position {}", position))]
62    DecodeItemHeader {
63        position: u64,
64        #[snafu(backtrace)]
65        source: dicom_encoding::decode::Error,
66    },
67
68    #[snafu(display("Could not decode text at position {}", position))]
69    DecodeText {
70        position: u64,
71        #[snafu(backtrace)]
72        source: dicom_encoding::text::DecodeTextError,
73    },
74
75    #[snafu(display("Could not read value from source at position {}", position))]
76    ReadValueData {
77        position: u64,
78        source: std::io::Error,
79        backtrace: Backtrace,
80    },
81
82    #[snafu(display(
83        "Could not move source cursor from position {} to {}",
84        position,
85        new_position
86    ))]
87    SeekReader {
88        position: u64,
89        new_position: u64,
90        source: std::io::Error,
91        backtrace: Backtrace,
92    },
93
94    #[snafu(display("Failed value deserialization at position {}", position))]
95    DeserializeValue {
96        position: u64,
97        source: dicom_core::value::deserialize::Error,
98    },
99
100    #[snafu(display("Invalid integer value at position {}", position))]
101    ReadInt {
102        position: u64,
103        source: std::num::ParseIntError,
104    },
105
106    #[snafu(display("Invalid float value at position {}", position))]
107    ReadFloat {
108        position: u64,
109        source: std::num::ParseFloatError,
110    },
111
112    #[snafu(display("Invalid Date value element `{}` at position {}", string, position))]
113    InvalidDateValue {
114        position: u64,
115        string: String,
116        backtrace: Backtrace,
117    },
118
119    #[snafu(display("Invalid Time value element `{}` at position {}", string, position))]
120    InvalidTimeValue {
121        position: u64,
122        string: String,
123        backtrace: Backtrace,
124    },
125
126    #[snafu(display("Invalid DateTime value element `{}` at position {}", string, position))]
127    InvalidDateTimeValue {
128        position: u64,
129        string: String,
130        backtrace: Backtrace,
131    },
132}
133
134pub type Result<T, E = Error> = std::result::Result<T, E>;
135
136pub trait StatefulDecode {
137    type Reader: Read;
138
139    /// Same as `Decode::decode_header` over the bound source.
140    fn decode_header(&mut self) -> Result<DataElementHeader>;
141
142    /// Same as `Decode::decode_item_header` over the bound source.
143    fn decode_item_header(&mut self) -> Result<SequenceItemHeader>;
144
145    /// Eagerly read the following data in the source as a primitive data
146    /// value. When reading values in text form, a conversion to a more
147    /// maleable type is attempted. Namely, numbers in text form (IS, DS) are
148    /// converted to the corresponding binary number types, and date/time
149    /// instances are decoded into binary date/time objects of types defined in
150    /// the `chrono` crate. To avoid this conversion, see
151    /// `read_value_preserved`.
152    ///
153    /// # Errors
154    ///
155    /// Returns an error on I/O problems, or if the header VR describes a
156    /// sequence, which in that case this method should not be used.
157    fn read_value(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue>;
158
159    /// Eagerly read the following data in the source as a primitive data
160    /// value. Unlike `read_value`, this method will preserve the DICOM value's
161    /// original format: numbers saved as text, as well as dates and times, are
162    /// read as strings.
163    ///
164    /// # Errors
165    ///
166    /// Returns an error on I/O problems, or if the header VR describes a
167    /// sequence, which in that case this method should not be used.
168    fn read_value_preserved(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue>;
169
170    /// Eagerly read the following data in the source as a primitive data
171    /// value as bytes, regardless of its value representation.
172    ///
173    /// # Errors
174    ///
175    /// Returns an error on I/O problems, or if the header VR describes a
176    /// sequence, which in that case this method should not be used.
177    fn read_value_bytes(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue>;
178
179    /// Read the following number of bytes into a vector.
180    fn read_to_vec(&mut self, length: u32, vec: &mut Vec<u8>) -> Result<()>;
181
182    /// Read the following number of bytes
183    /// as a sequence of unsigned 32 bit integers
184    /// into a vector.
185    fn read_u32_to_vec(&mut self, length: u32, vec: &mut Vec<u32>) -> Result<()>;
186
187    /// Read the following number of bytes into a generic writer.
188    fn read_to<W>(&mut self, length: u32, out: W) -> Result<()>
189    where
190        Self: Sized,
191        W: std::io::Write;
192
193    /// Skip the following bytes into a vector,
194    /// counting them as if they were read.
195    fn skip_bytes(&mut self, length: u32) -> Result<()>;
196
197    /// Reposition the reader so that it starts reading
198    /// at the reader's given position.
199    ///
200    /// The number of bytes read is not expected to be modified.
201    fn seek(&mut self, position: u64) -> Result<()>
202    where
203        Self::Reader: Seek;
204
205    /// Retrieve the known position of the inner reader source.
206    /// If the stateful decoder was constructed at the beginning of the reader,
207    /// this equals to the number of bytes read so far.
208    fn position(&self) -> u64;
209}
210
211/// Alias for a dynamically resolved DICOM stateful decoder. Although the data
212/// source may be known at compile time, the required decoder may vary
213/// according to an object's transfer syntax.
214pub type DynStatefulDecoder<S> = StatefulDecoder<DynDecoder<S>, S>;
215
216/// The initial capacity of the `DicomParser` buffer.
217const PARSER_BUFFER_CAPACITY: usize = 2048;
218
219/// A stateful abstraction for the full DICOM content reading process.
220/// This type encapsulates the necessary codecs in order
221/// to be as autonomous as possible in the DICOM content reading
222/// process.
223/// `S` is the generic parameter type for the original source,
224/// `D` is the parameter type that the decoder interprets as,
225/// whereas `DB` is the parameter type for the basic decoder.
226/// `TC` defines the text codec used underneath.
227#[derive(Debug)]
228pub struct StatefulDecoder<D, S, BD = BasicDecoder, TC = SpecificCharacterSet> {
229    from: S,
230    decoder: D,
231    basic: BD,
232    text: TC,
233    buffer: Vec<u8>,
234    /// the assumed position of the reader source
235    position: u64,
236    signed_pixeldata: Option<bool>,
237}
238
239impl<S> StatefulDecoder<DynDecoder<S>, S> {
240    /// Create a new DICOM parser for the given transfer syntax, character set,
241    /// and assumed position of the reader source.
242    pub fn new_with(
243        from: S,
244        ts: &TransferSyntax,
245        charset: SpecificCharacterSet,
246        position: u64,
247    ) -> Result<Self>
248    where
249        S: Read,
250    {
251        let basic = ts.basic_decoder();
252        let decoder = ts
253            .decoder_for::<S>()
254            .context(UnsupportedTransferSyntaxSnafu { ts: ts.name() })?;
255
256        Ok(StatefulDecoder::new_with_position(
257            from, decoder, basic, charset, position,
258        ))
259    }
260
261    /// Create a new DICOM parser for the given transfer syntax
262    /// and assumed position of the reader source.
263    ///
264    /// The default character set is assumed
265    /// until a _Specific Character Set_ attribute is found.
266    pub fn new_with_ts(from: S, ts: &TransferSyntax, position: u64) -> Result<Self>
267    where
268        S: Read,
269    {
270        Self::new_with(from, ts, SpecificCharacterSet::default(), position)
271    }
272}
273
274/// Type alias for the DICOM parser of a file's Meta group.
275pub type FileHeaderParser<S> = StatefulDecoder<
276    ExplicitVRLittleEndianDecoder,
277    S,
278    LittleEndianBasicDecoder,
279    DefaultCharacterSetCodec,
280>;
281
282impl<S> FileHeaderParser<S>
283where
284    S: Read,
285{
286    /// Create a new DICOM stateful decoder for reading the file meta header,
287    /// which is always in _Explicit VR Little Endian_.
288    pub fn file_header_parser(from: S) -> Self {
289        Self {
290            from,
291            basic: LittleEndianBasicDecoder,
292            decoder: ExplicitVRLittleEndianDecoder::default(),
293            text: DefaultCharacterSetCodec,
294            buffer: Vec::with_capacity(PARSER_BUFFER_CAPACITY),
295            position: 0,
296            signed_pixeldata: None,
297        }
298    }
299}
300
301impl<D, S, BD, TC> StatefulDecoder<D, S, BD, TC>
302where
303    BD: BasicDecode,
304    TC: TextCodec,
305{
306    /// Create a new DICOM stateful decoder from its parts.
307    #[inline]
308    pub fn new(from: S, decoder: D, basic: BD, text: TC) -> StatefulDecoder<D, S, BD, TC> {
309        Self::new_with_position(from, decoder, basic, text, 0)
310    }
311
312    /// Create a new DICOM stateful decoder from its parts,
313    /// while assuming a base reading position.
314    ///
315    /// `position` should be calculated with care.
316    /// Decoding or parsing errors may occur
317    /// if this position does not match the real position of the reader.
318    #[inline]
319    pub fn new_with_position(from: S, decoder: D, basic: BD, text: TC, position: u64) -> Self {
320        Self {
321            from,
322            basic,
323            decoder,
324            text,
325            buffer: Vec::with_capacity(PARSER_BUFFER_CAPACITY),
326            position,
327            signed_pixeldata: None,
328        }
329    }
330}
331
332impl<D, S, BD, TC> StatefulDecoder<D, S, BD, TC>
333where
334    S: Seek,
335    BD: BasicDecode,
336    TC: TextCodec,
337{
338    /// Create a new DICOM stateful decoder from its parts,
339    /// while determining the data source's current position via `seek`.
340    pub fn new_positioned(
341        mut from: S,
342        decoder: D,
343        basic: BD,
344        text: TC,
345    ) -> Result<Self, std::io::Error> {
346        let position = from.stream_position()?;
347        Ok(Self::new_with_position(
348            from, decoder, basic, text, position,
349        ))
350    }
351}
352
353impl<D, S, BD, TC> StatefulDecoder<D, S, BD, TC>
354where
355    D: DecodeFrom<S>,
356    BD: BasicDecode,
357    S: Read,
358    TC: TextCodec,
359{
360    // ---------------- private methods ---------------------
361
362    fn require_known_length(&self, header: &DataElementHeader) -> Result<usize> {
363        header
364            .length()
365            .get()
366            .map(|len| len as usize)
367            .context(UndefinedValueLengthSnafu {
368                position: self.position,
369                tag: header.tag,
370            })
371    }
372
373    fn read_value_tag(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
374        let len = self.require_known_length(header)?;
375
376        // tags
377        let ntags = len >> 2;
378        let parts: Result<_> = n_times(ntags)
379            .map(|_| {
380                self.basic
381                    .decode_tag(&mut self.from)
382                    .context(ReadValueDataSnafu {
383                        position: self.position,
384                    })
385            })
386            .collect();
387        self.position += len as u64;
388        Ok(PrimitiveValue::Tags(parts?))
389    }
390
391    fn read_value_ob(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
392        // Note: this function always expects a defined length OB value
393        // (pixel sequence detection needs to be done by the caller)
394        let len = self.require_known_length(header)?;
395
396        // sequence of 8-bit integers (or arbitrary byte data)
397        let mut buf = smallvec![0u8; len];
398        self.from.read_exact(&mut buf).context(ReadValueDataSnafu {
399            position: self.position,
400        })?;
401        self.position += len as u64;
402        Ok(PrimitiveValue::U8(buf))
403    }
404
405    fn read_value_strs(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
406        let len = self.require_known_length(header)?;
407        // sequence of strings
408        self.buffer.resize_with(len, Default::default);
409        self.from
410            .read_exact(&mut self.buffer)
411            .context(ReadValueDataSnafu {
412                position: self.position,
413            })?;
414
415        let parts: Result<_> = match header.vr() {
416            VR::AE | VR::CS | VR::AS => self
417                .buffer
418                .split(|v| *v == b'\\')
419                .map(|slice| {
420                    DefaultCharacterSetCodec
421                        .decode(slice)
422                        .context(DecodeTextSnafu {
423                            position: self.position,
424                        })
425                })
426                .collect(),
427            _ => self
428                .buffer
429                .split(|v| *v == b'\\')
430                .map(|slice| {
431                    self.text.decode(slice).context(DecodeTextSnafu {
432                        position: self.position,
433                    })
434                })
435                .collect(),
436        };
437
438        self.position += len as u64;
439        Ok(PrimitiveValue::Strs(parts?))
440    }
441
442    fn read_value_str(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
443        let len = self.require_known_length(header)?;
444
445        // a single string
446        self.buffer.resize_with(len, Default::default);
447        self.from
448            .read_exact(&mut self.buffer)
449            .context(ReadValueDataSnafu {
450                position: self.position,
451            })?;
452        self.position += len as u64;
453        Ok(PrimitiveValue::Str(
454            self.text
455                .decode(&self.buffer[..])
456                .context(DecodeTextSnafu {
457                    position: self.position,
458                })?,
459        ))
460    }
461
462    fn read_value_ss(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
463        // sequence of 16-bit signed integers
464        let len = self.require_known_length(header)?;
465
466        let n = len >> 1;
467        let mut vec = smallvec![0; n];
468        self.basic
469            .decode_ss_into(&mut self.from, &mut vec[..])
470            .context(ReadValueDataSnafu {
471                position: self.position,
472            })?;
473
474        self.position += len as u64;
475        Ok(PrimitiveValue::I16(vec))
476    }
477
478    fn read_value_fl(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
479        let len = self.require_known_length(header)?;
480        // sequence of 32-bit floats
481        let n = len >> 2;
482        let mut vec = smallvec![0.; n];
483        self.basic
484            .decode_fl_into(&mut self.from, &mut vec[..])
485            .context(ReadValueDataSnafu {
486                position: self.position,
487            })?;
488        self.position += len as u64;
489        Ok(PrimitiveValue::F32(vec))
490    }
491
492    fn read_value_da(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
493        let len = self.require_known_length(header)?;
494        // sequence of dates
495
496        self.buffer.resize_with(len, Default::default);
497        self.from
498            .read_exact(&mut self.buffer)
499            .context(ReadValueDataSnafu {
500                position: self.position,
501            })?;
502        let buf = trim_trail_empty_bytes(&self.buffer);
503        if buf.is_empty() {
504            return Ok(PrimitiveValue::Empty);
505        }
506
507        if validate_da(buf) != TextValidationOutcome::Ok {
508            let lossy_str = DefaultCharacterSetCodec
509                .decode(buf)
510                .unwrap_or_else(|_| "[byte stream]".to_string());
511            return InvalidDateValueSnafu {
512                position: self.position,
513                string: lossy_str,
514            }
515            .fail();
516        }
517        let vec: Result<_> = buf
518            .split(|b| *b == b'\\')
519            .map(|part| {
520                parse_date_partial(part)
521                    .map(|t| t.0)
522                    .context(DeserializeValueSnafu {
523                        position: self.position,
524                    })
525            })
526            .collect();
527        self.position += len as u64;
528        Ok(PrimitiveValue::Date(vec?))
529    }
530
531    fn read_value_ds(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
532        let len = self.require_known_length(header)?;
533        // sequence of doubles in text form
534
535        self.buffer.resize_with(len, Default::default);
536        self.from
537            .read_exact(&mut self.buffer)
538            .context(ReadValueDataSnafu {
539                position: self.position,
540            })?;
541        let buf = trim_trail_empty_bytes(&self.buffer);
542        if buf.is_empty() {
543            return Ok(PrimitiveValue::Empty);
544        }
545
546        let parts: Result<_> = buf
547            .split(|b| *b == b'\\')
548            .map(|slice| {
549                let codec = DefaultCharacterSetCodec;
550                let txt = codec.decode(slice).context(DecodeTextSnafu {
551                    position: self.position,
552                })?;
553                let txt = txt.trim();
554                txt.parse::<f64>().context(ReadFloatSnafu {
555                    position: self.position,
556                })
557            })
558            .collect();
559        self.position += len as u64;
560        Ok(PrimitiveValue::F64(parts?))
561    }
562
563    fn read_value_dt(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
564        let len = self.require_known_length(header)?;
565        // sequence of datetimes
566
567        self.buffer.resize_with(len, Default::default);
568        self.from
569            .read_exact(&mut self.buffer)
570            .context(ReadValueDataSnafu {
571                position: self.position,
572            })?;
573        let buf = trim_trail_empty_bytes(&self.buffer);
574        if buf.is_empty() {
575            return Ok(PrimitiveValue::Empty);
576        }
577
578        if validate_dt(buf) != TextValidationOutcome::Ok {
579            let lossy_str = DefaultCharacterSetCodec
580                .decode(buf)
581                .unwrap_or_else(|_| "[byte stream]".to_string());
582            return InvalidDateTimeValueSnafu {
583                position: self.position,
584                string: lossy_str,
585            }
586            .fail();
587        }
588        let vec: Result<_> = buf
589            .split(|b| *b == b'\\')
590            .map(|part| {
591                parse_datetime_partial(part).context(DeserializeValueSnafu {
592                    position: self.position,
593                })
594            })
595            .collect();
596
597        self.position += len as u64;
598        Ok(PrimitiveValue::DateTime(vec?))
599    }
600
601    fn read_value_is(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
602        let len = self.require_known_length(header)?;
603        // sequence of signed integers in text form
604        self.buffer.resize_with(len, Default::default);
605        self.from
606            .read_exact(&mut self.buffer)
607            .context(ReadValueDataSnafu {
608                position: self.position,
609            })?;
610        let buf = trim_trail_empty_bytes(&self.buffer);
611        if buf.is_empty() {
612            return Ok(PrimitiveValue::Empty);
613        }
614
615        let parts: Result<_> = buf
616            .split(|v| *v == b'\\')
617            .map(|slice| {
618                let codec = DefaultCharacterSetCodec;
619                let txt = codec.decode(slice).context(DecodeTextSnafu {
620                    position: self.position,
621                })?;
622                let txt = txt.trim();
623                txt.parse::<i32>().context(ReadIntSnafu {
624                    position: self.position,
625                })
626            })
627            .collect();
628        self.position += len as u64;
629        Ok(PrimitiveValue::I32(parts?))
630    }
631
632    fn read_value_tm(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
633        let len = self.require_known_length(header)?;
634        // sequence of time instances
635
636        self.buffer.resize_with(len, Default::default);
637        self.from
638            .read_exact(&mut self.buffer)
639            .context(ReadValueDataSnafu {
640                position: self.position,
641            })?;
642        let buf = trim_trail_empty_bytes(&self.buffer);
643        if buf.is_empty() {
644            return Ok(PrimitiveValue::Empty);
645        }
646
647        if validate_tm(buf) != TextValidationOutcome::Ok {
648            let lossy_str = DefaultCharacterSetCodec
649                .decode(buf)
650                .unwrap_or_else(|_| "[byte stream]".to_string());
651            return InvalidTimeValueSnafu {
652                position: self.position,
653                string: lossy_str,
654            }
655            .fail();
656        }
657        let vec: std::result::Result<_, _> = buf
658            .split(|b| *b == b'\\')
659            .map(|part| {
660                parse_time_partial(part)
661                    .map(|t| t.0)
662                    .context(DeserializeValueSnafu {
663                        position: self.position,
664                    })
665            })
666            .collect();
667        self.position += len as u64;
668        Ok(PrimitiveValue::Time(vec?))
669    }
670
671    fn read_value_od(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
672        let len = self.require_known_length(header)?;
673        // sequence of 64-bit floats
674        let n = len >> 3;
675        let mut vec = smallvec![0.; n];
676        self.basic
677            .decode_fd_into(&mut self.from, &mut vec[..])
678            .context(ReadValueDataSnafu {
679                position: self.position,
680            })?;
681        self.position += len as u64;
682        Ok(PrimitiveValue::F64(vec))
683    }
684
685    fn read_value_ul(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
686        let len = self.require_known_length(header)?;
687        // sequence of 32-bit unsigned integers
688
689        let n = len >> 2;
690        let mut vec = smallvec![0u32; n];
691        self.basic
692            .decode_ul_into(&mut self.from, &mut vec[..])
693            .context(ReadValueDataSnafu {
694                position: self.position,
695            })?;
696        self.position += len as u64;
697        Ok(PrimitiveValue::U32(vec))
698    }
699
700    fn read_u32(&mut self, n: usize, vec: &mut Vec<u32>) -> Result<()> {
701        let base = vec.len();
702        vec.resize(base + n, 0);
703
704        self.basic
705            .decode_ul_into(&mut self.from, &mut vec[base..])
706            .context(ReadValueDataSnafu {
707                position: self.position,
708            })?;
709        self.position += n as u64 * 4;
710        Ok(())
711    }
712
713    fn read_value_us(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
714        let len = self.require_known_length(header)?;
715        // sequence of 16-bit unsigned integers
716
717        let n = len >> 1;
718        let mut vec = smallvec![0; n];
719        self.basic
720            .decode_us_into(&mut self.from, &mut vec[..])
721            .context(ReadValueDataSnafu {
722                position: self.position,
723            })?;
724
725        self.position += len as u64;
726
727        if header.tag == Tag(0x0028, 0x0103) {
728            //Pixel Representation is not 0, so 2s complement (signed)
729            self.signed_pixeldata = vec.first().map(|rep| *rep != 0);
730        }
731
732        Ok(PrimitiveValue::U16(vec))
733    }
734
735    fn read_value_uv(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
736        let len = self.require_known_length(header)?;
737        // sequence of 64-bit unsigned integers
738
739        let n = len >> 3;
740        let mut vec = smallvec![0; n];
741        self.basic
742            .decode_uv_into(&mut self.from, &mut vec[..])
743            .context(ReadValueDataSnafu {
744                position: self.position,
745            })?;
746        self.position += len as u64;
747        Ok(PrimitiveValue::U64(vec))
748    }
749
750    fn read_value_sl(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
751        let len = self.require_known_length(header)?;
752        // sequence of 32-bit signed integers
753
754        let n = len >> 2;
755        let mut vec = smallvec![0; n];
756        self.basic
757            .decode_sl_into(&mut self.from, &mut vec[..])
758            .context(ReadValueDataSnafu {
759                position: self.position,
760            })?;
761        self.position += len as u64;
762        Ok(PrimitiveValue::I32(vec))
763    }
764
765    fn read_value_sv(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
766        let len = self.require_known_length(header)?;
767        // sequence of 64-bit signed integers
768
769        let n = len >> 3;
770        let mut vec = smallvec![0; n];
771        self.basic
772            .decode_sv_into(&mut self.from, &mut vec[..])
773            .context(ReadValueDataSnafu {
774                position: self.position,
775            })?;
776        self.position += len as u64;
777        Ok(PrimitiveValue::I64(vec))
778    }
779}
780
781impl<S, D, BD> StatefulDecoder<D, S, BD>
782where
783    D: DecodeFrom<S>,
784    BD: BasicDecode,
785    S: Read,
786{
787    fn set_character_set(&mut self, charset: SpecificCharacterSet) -> Result<()> {
788        self.text = charset;
789        Ok(())
790    }
791
792    /// Read a sequence of Code String values. Similar to `read_value_strs`, but also
793    /// triggers a character set change when it finds the _SpecificCharacterSet_
794    /// attribute.
795    fn read_value_cs(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
796        let out = self.read_value_strs(header)?;
797
798        let parts = match &out {
799            PrimitiveValue::Strs(parts) => parts,
800            _ => unreachable!(),
801        };
802
803        // if it's a Specific Character Set, update the decoder immediately.
804        if header.tag == Tag(0x0008, 0x0005) {
805            // Edge case handling strategies for
806            // unsupported specific character sets should probably be considered
807            // in the future. See #40 for discussion.
808            if let Some(charset) = parts.first().map(|x| x.as_ref()).and_then(|name| {
809                SpecificCharacterSet::from_code(name).or_else(|| {
810                    tracing::warn!("Unsupported character set `{}`, ignoring", name);
811                    None
812                })
813            }) {
814                self.set_character_set(charset)?;
815            }
816        }
817
818        Ok(out)
819    }
820}
821
822impl<D> StatefulDecode for &'_ mut D
823where
824    D: StatefulDecode,
825{
826    type Reader = D::Reader;
827
828    fn decode_header(&mut self) -> Result<DataElementHeader> {
829        (**self).decode_header()
830    }
831
832    fn decode_item_header(&mut self) -> Result<SequenceItemHeader> {
833        (**self).decode_item_header()
834    }
835
836    fn read_value(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
837        (**self).read_value(header)
838    }
839
840    fn read_value_preserved(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
841        (**self).read_value_preserved(header)
842    }
843
844    fn read_value_bytes(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
845        (**self).read_value_bytes(header)
846    }
847
848    fn read_to_vec(&mut self, length: u32, vec: &mut Vec<u8>) -> Result<()> {
849        (**self).read_to_vec(length, vec)
850    }
851
852    fn read_u32_to_vec(&mut self, length: u32, vec: &mut Vec<u32>) -> Result<()> {
853        (**self).read_u32_to_vec(length, vec)
854    }
855
856    fn read_to<W>(&mut self, length: u32, out: W) -> Result<()>
857    where
858        Self: Sized,
859        W: std::io::Write,
860    {
861        (**self).read_to(length, out)
862    }
863
864    fn skip_bytes(&mut self, length: u32) -> Result<()> {
865        (**self).skip_bytes(length)
866    }
867
868    fn position(&self) -> u64 {
869        (**self).position()
870    }
871
872    fn seek(&mut self, position: u64) -> Result<()>
873    where
874        Self::Reader: Seek,
875    {
876        (**self).seek(position)
877    }
878}
879
880impl<D, S, BD> StatefulDecode for StatefulDecoder<D, S, BD>
881where
882    D: DecodeFrom<S>,
883    BD: BasicDecode,
884    S: Read,
885{
886    type Reader = S;
887
888    fn decode_header(&mut self) -> Result<DataElementHeader> {
889        let mut header = self
890            .decoder
891            .decode_header(&mut self.from)
892            .context(DecodeElementHeaderSnafu {
893                position: self.position,
894            })
895            .map(|(header, bytes_read)| {
896                self.position += bytes_read as u64;
897                header
898            })
899            .map_err(From::from)?;
900
901        //If we are decoding the PixelPadding element, make sure the VR is the same as the pixel
902        //representation (US by default, SS for signed data).
903        if let Some(vr) = self.determine_vr_based_on_pixel_representation(header.tag) {
904            header.vr = vr;
905        }
906
907        Ok(header)
908    }
909
910    fn decode_item_header(&mut self) -> Result<SequenceItemHeader> {
911        self.decoder
912            .decode_item_header(&mut self.from)
913            .context(DecodeItemHeaderSnafu {
914                position: self.position,
915            })
916            .map(|header| {
917                self.position += 8;
918                header
919            })
920            .map_err(From::from)
921    }
922
923    fn read_value(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
924        if header.length() == Length(0) {
925            return Ok(PrimitiveValue::Empty);
926        }
927
928        match header.vr() {
929            VR::SQ => {
930                // sequence objects should not head over here, they are
931                // handled at a higher level
932                NonPrimitiveTypeSnafu {
933                    position: self.position,
934                }
935                .fail()
936            }
937            VR::AT => self.read_value_tag(header),
938            VR::AE | VR::AS | VR::PN | VR::SH | VR::LO | VR::UC | VR::UI => {
939                self.read_value_strs(header)
940            }
941            VR::CS => self.read_value_cs(header),
942            VR::UT | VR::ST | VR::UR | VR::LT => self.read_value_str(header),
943            VR::UN | VR::OB => self.read_value_ob(header),
944            VR::US | VR::OW => self.read_value_us(header),
945            VR::SS => self.read_value_ss(header),
946            VR::DA => self.read_value_da(header),
947            VR::DT => self.read_value_dt(header),
948            VR::TM => self.read_value_tm(header),
949            VR::DS => self.read_value_ds(header),
950            VR::FD | VR::OD => self.read_value_od(header),
951            VR::FL | VR::OF => self.read_value_fl(header),
952            VR::IS => self.read_value_is(header),
953            VR::SL => self.read_value_sl(header),
954            VR::SV => self.read_value_sv(header),
955            VR::OL | VR::UL => self.read_value_ul(header),
956            VR::OV | VR::UV => self.read_value_uv(header),
957        }
958    }
959
960    fn read_value_preserved(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
961        if header.length() == Length(0) {
962            return Ok(PrimitiveValue::Empty);
963        }
964
965        match header.vr() {
966            VR::SQ => {
967                // sequence objects... should not work
968                NonPrimitiveTypeSnafu {
969                    position: self.position,
970                }
971                .fail()
972            }
973            VR::AT => self.read_value_tag(header),
974            VR::AE
975            | VR::AS
976            | VR::PN
977            | VR::SH
978            | VR::LO
979            | VR::UC
980            | VR::UI
981            | VR::IS
982            | VR::DS
983            | VR::DA
984            | VR::TM
985            | VR::DT => self.read_value_strs(header),
986            VR::CS => self.read_value_cs(header),
987            VR::UT | VR::ST | VR::UR | VR::LT => self.read_value_str(header),
988            VR::UN | VR::OB => self.read_value_ob(header),
989            VR::US | VR::OW => self.read_value_us(header),
990            VR::SS => self.read_value_ss(header),
991            VR::FD | VR::OD => self.read_value_od(header),
992            VR::FL | VR::OF => self.read_value_fl(header),
993            VR::SL => self.read_value_sl(header),
994            VR::OL | VR::UL => self.read_value_ul(header),
995            VR::SV => self.read_value_sv(header),
996            VR::OV | VR::UV => self.read_value_uv(header),
997        }
998    }
999
1000    fn read_value_bytes(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
1001        if header.length() == Length(0) {
1002            return Ok(PrimitiveValue::Empty);
1003        }
1004
1005        match header.vr() {
1006            VR::SQ => {
1007                // sequence objects... should not work
1008                NonPrimitiveTypeSnafu {
1009                    position: self.position,
1010                }
1011                .fail()
1012            }
1013            _ => self.read_value_ob(header),
1014        }
1015    }
1016
1017    fn position(&self) -> u64 {
1018        self.position
1019    }
1020
1021    fn read_to_vec(&mut self, length: u32, vec: &mut Vec<u8>) -> Result<()> {
1022        self.read_to(length, vec)
1023    }
1024
1025    fn read_u32_to_vec(&mut self, length: u32, vec: &mut Vec<u32>) -> Result<()> {
1026        self.read_u32((length >> 2) as usize, vec)
1027    }
1028
1029    fn read_to<W>(&mut self, length: u32, mut out: W) -> Result<()>
1030    where
1031        Self: Sized,
1032        W: std::io::Write,
1033    {
1034        let length = u64::from(length);
1035        std::io::copy(&mut self.from.by_ref().take(length), &mut out).context(
1036            ReadValueDataSnafu {
1037                position: self.position,
1038            },
1039        )?;
1040        self.position += length;
1041        Ok(())
1042    }
1043
1044    fn skip_bytes(&mut self, length: u32) -> Result<()> {
1045        std::io::copy(
1046            &mut self.from.by_ref().take(u64::from(length)),
1047            &mut std::io::sink(),
1048        )
1049        .context(ReadValueDataSnafu {
1050            position: self.position,
1051        })?;
1052
1053        self.position += u64::from(length);
1054        Ok(())
1055    }
1056
1057    fn seek(&mut self, position: u64) -> Result<()>
1058    where
1059        Self::Reader: Seek,
1060    {
1061        self.from
1062            .seek(SeekFrom::Start(position))
1063            .context(SeekReaderSnafu {
1064                position: self.position,
1065                new_position: position,
1066            })
1067            .map(|_| ())
1068    }
1069}
1070
1071impl<D, S, BD> StatefulDecoder<D, S, BD>
1072where
1073    D: DecodeFrom<S>,
1074    BD: BasicDecode,
1075    S: Read,
1076{
1077    /// The pixel representation affects the VR for several elements.
1078    /// Returns `Some(VR::SS)` if the vr needs to be modified to SS. Returns `None`
1079    /// if this element is not affected _or_ if we have Unsigned Pixel Representation.
1080    fn determine_vr_based_on_pixel_representation(&self, tag: Tag) -> Option<VR> {
1081        use dicom_core::dictionary::DataDictionary;
1082
1083        if self.signed_pixeldata == Some(true)
1084            && StandardDataDictionary.by_tag(tag).map(|e| e.vr) == Some(VirtualVr::Xs)
1085        {
1086            Some(VR::SS)
1087        } else {
1088            None
1089        }
1090    }
1091}
1092
1093/// Remove trailing spaces and null characters.
1094fn trim_trail_empty_bytes(mut x: &[u8]) -> &[u8] {
1095    while x.last() == Some(&b' ') || x.last() == Some(&b'\0') {
1096        x = &x[..x.len() - 1];
1097    }
1098    x
1099}
1100
1101#[cfg(test)]
1102mod tests {
1103    use super::{StatefulDecode, StatefulDecoder};
1104    use dicom_core::header::{DataElementHeader, HasLength, Header, Length, SequenceItemHeader};
1105    use dicom_core::{Tag, VR};
1106    use dicom_encoding::decode::basic::LittleEndianBasicDecoder;
1107    use dicom_encoding::decode::{
1108        explicit_le::ExplicitVRLittleEndianDecoder, implicit_le::ImplicitVRLittleEndianDecoder,
1109    };
1110    use dicom_encoding::text::{SpecificCharacterSet, TextCodec};
1111    use std::io::{Cursor, Seek, SeekFrom};
1112
1113    // manually crafting some DICOM data elements
1114    //  Tag: (0002,0002) Media Storage SOP Class UID
1115    //  VR: UI
1116    //  Length: 26
1117    //  Value: "1.2.840.10008.5.1.4.1.1.1\0"
1118    // --
1119    //  Tag: (0002,0010) Transfer Syntax UID
1120    //  VR: UI
1121    //  Length: 20
1122    //  Value: "1.2.840.10008.1.2.1\0" == ExplicitVRLittleEndian
1123    // --
1124    const RAW: &'static [u8; 62] = &[
1125        0x02, 0x00, 0x02, 0x00, 0x55, 0x49, 0x1a, 0x00, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
1126        0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
1127        0x31, 0x2e, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x55, 0x49, 0x14, 0x00, 0x31, 0x2e, 0x32,
1128        0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
1129        0x31, 0x00,
1130    ];
1131
1132    fn is_stateful_decoder<T>(_: &T)
1133    where
1134        T: StatefulDecode,
1135    {
1136    }
1137
1138    #[test]
1139    fn decode_data_elements() {
1140        let mut cursor = Cursor::new(&RAW[..]);
1141        let mut decoder = StatefulDecoder::new(
1142            &mut cursor,
1143            ExplicitVRLittleEndianDecoder::default(),
1144            LittleEndianBasicDecoder,
1145            SpecificCharacterSet::default(),
1146        );
1147
1148        is_stateful_decoder(&decoder);
1149
1150        {
1151            // read first element
1152            let elem = decoder.decode_header().expect("should find an element");
1153            assert_eq!(elem.tag(), Tag(2, 2));
1154            assert_eq!(elem.vr(), VR::UI);
1155            assert_eq!(elem.length(), Length(26));
1156
1157            assert_eq!(decoder.position(), 8);
1158
1159            // read value
1160            let value = decoder
1161                .read_value(&elem)
1162                .expect("value after element header");
1163            assert_eq!(value.multiplicity(), 1);
1164            assert_eq!(value.string(), Ok("1.2.840.10008.5.1.4.1.1.1\0"));
1165
1166            assert_eq!(decoder.position(), 8 + 26);
1167        }
1168        {
1169            // read second element
1170            let elem = decoder.decode_header().expect("should find an element");
1171            assert_eq!(elem.tag(), Tag(2, 16));
1172            assert_eq!(elem.vr(), VR::UI);
1173            assert_eq!(elem.length(), Length(20));
1174
1175            assert_eq!(decoder.position(), 8 + 26 + 8);
1176
1177            // read value
1178            let value = decoder
1179                .read_value(&elem)
1180                .expect("value after element header");
1181            assert_eq!(value.multiplicity(), 1);
1182            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1183
1184            assert_eq!(decoder.position(), 8 + 26 + 8 + 20);
1185
1186            // rolling back to read the last value again
1187            decoder.seek(8 + 26 + 8).unwrap();
1188
1189            // read value
1190            let value = decoder
1191                .read_value(&elem)
1192                .expect("value after element header");
1193            assert_eq!(value.multiplicity(), 1);
1194            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1195
1196            assert_eq!(decoder.position(), 8 + 26 + 8 + 20 + 20);
1197        }
1198    }
1199
1200    /// Test that the stateful decoder updates
1201    /// the active character set after reaching a Specific Character Set element
1202    /// with a supported text encoding.
1203    #[test]
1204    fn update_character_set() {
1205        const RAW: &'static [u8; 18] = &[
1206            // Tag: (0008,0005) Specific Character Set
1207            0x08, 0x00, 0x05, 0x00, // VR: CS
1208            b'C', b'S', // Length: 10
1209            0x0a, 0x00, // Value: "ISO_IR 192"
1210            b'I', b'S', b'O', b'_', b'I', b'R', b' ', b'1', b'9', b'2',
1211        ];
1212
1213        let mut cursor = &RAW[..];
1214        let mut decoder = StatefulDecoder::new(
1215            &mut cursor,
1216            ExplicitVRLittleEndianDecoder::default(),
1217            LittleEndianBasicDecoder,
1218            SpecificCharacterSet::default(),
1219        );
1220
1221        is_stateful_decoder(&decoder);
1222
1223        let header = decoder
1224            .decode_header()
1225            .expect("should find an element header");
1226        assert_eq!(
1227            header,
1228            DataElementHeader {
1229                tag: Tag(0x0008, 0x0005),
1230                vr: VR::CS,
1231                len: Length(10),
1232            }
1233        );
1234
1235        let value = decoder
1236            .read_value_preserved(&header)
1237            .expect("should read a value");
1238
1239        assert_eq!(value.string(), Ok("ISO_IR 192"));
1240        assert_eq!(decoder.text.name(), "ISO_IR 192",);
1241    }
1242
1243    #[test]
1244    fn decode_data_elements_with_position() {
1245        let data = {
1246            let mut x = vec![0; 128];
1247            x.extend(RAW);
1248            x
1249        };
1250
1251        // have cursor start 128 bytes ahead
1252        let mut cursor = Cursor::new(&data[..]);
1253        cursor.seek(SeekFrom::Start(128)).unwrap();
1254
1255        let mut decoder = StatefulDecoder::new_with_position(
1256            &mut cursor,
1257            ExplicitVRLittleEndianDecoder::default(),
1258            LittleEndianBasicDecoder,
1259            SpecificCharacterSet::default(),
1260            128,
1261        );
1262
1263        is_stateful_decoder(&decoder);
1264
1265        {
1266            // read first element
1267            let elem = decoder.decode_header().expect("should find an element");
1268            assert_eq!(elem.tag(), Tag(2, 2));
1269            assert_eq!(elem.vr(), VR::UI);
1270            assert_eq!(elem.length(), Length(26));
1271
1272            assert_eq!(decoder.position(), 128 + 8);
1273
1274            // read value
1275            let value = decoder
1276                .read_value(&elem)
1277                .expect("value after element header");
1278            assert_eq!(value.multiplicity(), 1);
1279            assert_eq!(value.string(), Ok("1.2.840.10008.5.1.4.1.1.1\0"));
1280
1281            assert_eq!(decoder.position(), 128 + 8 + 26);
1282        }
1283        {
1284            // read second element
1285            let elem = decoder.decode_header().expect("should find an element");
1286            assert_eq!(elem.tag(), Tag(2, 16));
1287            assert_eq!(elem.vr(), VR::UI);
1288            assert_eq!(elem.length(), Length(20));
1289
1290            assert_eq!(decoder.position(), 128 + 8 + 26 + 8);
1291
1292            // read value
1293            let value = decoder
1294                .read_value(&elem)
1295                .expect("value after element header");
1296            assert_eq!(value.multiplicity(), 1);
1297            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1298
1299            assert_eq!(decoder.position(), 128 + 8 + 26 + 8 + 20);
1300
1301            // rolling back to read the last value again
1302            decoder.seek(128 + 8 + 26 + 8).unwrap();
1303
1304            // read value
1305            let value = decoder
1306                .read_value(&elem)
1307                .expect("value after element header");
1308            assert_eq!(value.multiplicity(), 1);
1309            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1310
1311            assert_eq!(decoder.position(), 128 + 8 + 26 + 8 + 20 + 20);
1312        }
1313    }
1314
1315    #[test]
1316    fn decode_nested_datasets() {
1317        const RAW: &'static [u8; 138] = &[
1318            // 0: (2001, 9000) private sequence
1319            0x01, 0x20, 0x00, 0x90, //
1320            // length: undefined
1321            0xFF, 0xFF, 0xFF, 0xFF, //
1322            // 8: Item start
1323            0xFE, 0xFF, 0x00, 0xE0, //
1324            // Item length explicit (114)
1325            0x72, 0x00, 0x00, 0x00, //
1326            // 16: (0008,1115) ReferencedSeriesSequence
1327            0x08, 0x00, 0x15, 0x11, //
1328            // length: undefined
1329            0xFF, 0xFF, 0xFF, 0xFF, //
1330            // 24: Item start
1331            0xFE, 0xFF, 0x00, 0xE0, //
1332            // Item length undefined
1333            0xFF, 0xFF, 0xFF, 0xFF, //
1334            // 32: (0008,1140) ReferencedImageSequence
1335            0x08, 0x00, 0x40, 0x11, //
1336            // length: undefined
1337            0xFF, 0xFF, 0xFF, 0xFF, //
1338            // 40: Item start
1339            0xFE, 0xFF, 0x00, 0xE0, //
1340            // Item length undefined
1341            0xFF, 0xFF, 0xFF, 0xFF, //
1342            // 48: (0008,1150) ReferencedSOPClassUID
1343            0x08, 0x00, 0x50, 0x11, //
1344            // length: 26
1345            0x1a, 0x00, 0x00, 0x00, //
1346            // Value: "1.2.840.10008.5.1.4.1.1.7\0" (SecondaryCaptureImageStorage)
1347            b'1', b'.', b'2', b'.', b'8', b'4', b'0', b'.', b'1', b'0', b'0', b'0', b'8', b'.',
1348            b'5', b'.', b'1', b'.', b'4', b'.', b'1', b'.', b'1', b'.', b'7', b'\0',
1349            // 82: Item End (ReferencedImageSequence)
1350            0xFE, 0xFF, 0x0D, 0xE0, //
1351            0x00, 0x00, 0x00, 0x00, //
1352            // 90: Sequence End (ReferencedImageSequence)
1353            0xFE, 0xFF, 0xDD, 0xE0, //
1354            0x00, 0x00, 0x00, 0x00, //
1355            // 98: Item End (ReferencedSeriesSequence)
1356            0xFE, 0xFF, 0x0D, 0xE0, //
1357            0x00, 0x00, 0x00, 0x00, //
1358            // 106: Sequence End (ReferencedSeriesSequence)
1359            0xFE, 0xFF, 0xDD, 0xE0, //
1360            0x00, 0x00, 0x00, 0x00, //
1361            // 114: (2050,0020) PresentationLUTShape (CS)
1362            0x50, 0x20, 0x20, 0x00, //
1363            // length: 8
1364            0x08, 0x00, 0x00, 0x00, //
1365            b'I', b'D', b'E', b'N', b'T', b'I', b'T', b'Y', // 130: Sequence end
1366            0xFE, 0xFF, 0xDD, 0xE0, //
1367            0x00, 0x00, 0x00, 0x00, //
1368        ];
1369
1370        let mut cursor = &RAW[..];
1371        let mut decoder = StatefulDecoder::new(
1372            &mut cursor,
1373            ImplicitVRLittleEndianDecoder::default(),
1374            LittleEndianBasicDecoder,
1375            SpecificCharacterSet::default(),
1376        );
1377
1378        is_stateful_decoder(&decoder);
1379
1380        let header = decoder
1381            .decode_header()
1382            .expect("should find an element header");
1383        assert_eq!(header.tag(), Tag(0x2001, 0x9000));
1384        assert_eq!(header.vr(), VR::UN);
1385        assert!(header.length().is_undefined());
1386
1387        assert_eq!(decoder.position(), 8);
1388
1389        let item_header = decoder
1390            .decode_item_header()
1391            .expect("should find an item header");
1392        assert_eq!(item_header, SequenceItemHeader::Item { len: Length(114) });
1393
1394        assert_eq!(decoder.position(), 16);
1395
1396        // enter ReferencedSeriesSequence
1397        let header = decoder
1398            .decode_header()
1399            .expect("should find an element header");
1400        assert_eq!(header.tag(), Tag(0x0008, 0x1115));
1401        assert_eq!(header.vr(), VR::SQ);
1402        assert!(header.length().is_undefined());
1403
1404        assert_eq!(decoder.position(), 24);
1405
1406        let item_header = decoder
1407            .decode_item_header()
1408            .expect("should find an item header (ReferencedSeriesSequence)");
1409        assert!(matches!(
1410            item_header,
1411            SequenceItemHeader::Item {
1412                len,
1413            } if len.is_undefined()
1414        ));
1415
1416        assert_eq!(decoder.position(), 32);
1417
1418        // enter ReferencedImageSequence
1419        let header = decoder
1420            .decode_header()
1421            .expect("should find an element header");
1422        assert_eq!(header.tag(), Tag(0x0008, 0x1140));
1423        assert_eq!(header.vr(), VR::SQ);
1424        assert!(header.length().is_undefined());
1425
1426        assert_eq!(decoder.position(), 40);
1427
1428        let item_header = decoder
1429            .decode_item_header()
1430            .expect("should find an item header (ReferencedImageSequence)");
1431        assert!(matches!(
1432            item_header,
1433            SequenceItemHeader::Item {
1434                len,
1435            } if len.is_undefined()
1436        ));
1437
1438        assert_eq!(decoder.position(), 48);
1439
1440        // read ReferencedSOPClassUID
1441
1442        let header = decoder
1443            .decode_header()
1444            .expect("should find an element header");
1445        assert_eq!(header.tag(), Tag(0x0008, 0x1150));
1446        assert_eq!(header.vr(), VR::UI);
1447        assert_eq!(header.length(), Length(26));
1448
1449        assert_eq!(decoder.position(), 56);
1450
1451        let value = decoder
1452            .read_value(&header)
1453            .expect("should find a value after element header");
1454        assert_eq!(value.to_str(), "1.2.840.10008.5.1.4.1.1.7");
1455
1456        assert_eq!(decoder.position(), 82);
1457
1458        // exit ReferencedImageSequence
1459
1460        let item_header = decoder
1461            .decode_item_header()
1462            .expect("should find item delimiter");
1463        assert_eq!(item_header, SequenceItemHeader::ItemDelimiter);
1464
1465        assert_eq!(decoder.position(), 90);
1466
1467        let item_header = decoder
1468            .decode_item_header()
1469            .expect("should find sequence delimiter");
1470        assert_eq!(item_header, SequenceItemHeader::SequenceDelimiter);
1471
1472        assert_eq!(decoder.position(), 98);
1473
1474        // exit ReferencedSeriesSequence
1475
1476        let item_header = decoder
1477            .decode_item_header()
1478            .expect("should find item delimiter");
1479        assert_eq!(item_header, SequenceItemHeader::ItemDelimiter);
1480
1481        assert_eq!(decoder.position(), 106);
1482
1483        let item_header = decoder
1484            .decode_item_header()
1485            .expect("should find sequence delimiter");
1486        assert_eq!(item_header, SequenceItemHeader::SequenceDelimiter);
1487
1488        assert_eq!(decoder.position(), 114);
1489
1490        // read PresentationLUTShape
1491
1492        let header = decoder
1493            .decode_header()
1494            .expect("should find an element header");
1495        assert_eq!(header.tag(), Tag(0x2050, 0x0020));
1496        assert_eq!(header.vr(), VR::CS);
1497        assert_eq!(header.length(), Length(8));
1498
1499        assert_eq!(decoder.position(), 122);
1500
1501        let value = decoder
1502            .read_value(&header)
1503            .expect("value after element header");
1504        assert_eq!(value.multiplicity(), 1);
1505        assert_eq!(value.to_str(), "IDENTITY");
1506
1507        assert_eq!(decoder.position(), 130);
1508
1509        // exit private sequence
1510        // (no item delimiter because length is explicit)
1511
1512        let item_header = decoder
1513            .decode_item_header()
1514            .expect("should find an item header");
1515        assert_eq!(item_header, SequenceItemHeader::SequenceDelimiter);
1516
1517        assert_eq!(decoder.position(), 138);
1518    }
1519
1520    #[test]
1521    fn decode_and_use_pixel_representation() {
1522        const RAW: &'static [u8; 20] = &[
1523            0x28, 0x00, 0x03, 0x01, // Tag: (0023,0103) PixelRepresentation
1524            0x02, 0x00, 0x00, 0x00, // Length: 2
1525            0x01, 0x00, // Value: "1",
1526            0x28, 0x00, 0x20, 0x01, // Tag: (0023,0120) PixelPadding
1527            0x02, 0x00, 0x00, 0x00, // Length: 2
1528            0x01, 0x00, // Value: "1"
1529        ];
1530
1531        let mut cursor = &RAW[..];
1532        let mut decoder = StatefulDecoder::new(
1533            &mut cursor,
1534            ImplicitVRLittleEndianDecoder::default(),
1535            LittleEndianBasicDecoder,
1536            SpecificCharacterSet::default(),
1537        );
1538
1539        is_stateful_decoder(&decoder);
1540
1541        let header_1 = decoder
1542            .decode_header()
1543            .expect("should find an element header");
1544        assert_eq!(
1545            header_1,
1546            DataElementHeader {
1547                tag: Tag(0x0028, 0x0103),
1548                vr: VR::US,
1549                len: Length(2),
1550            }
1551        );
1552
1553        decoder
1554            .read_value(&header_1)
1555            .expect("Can read Pixel Representation");
1556
1557        let header_2 = decoder
1558            .decode_header()
1559            .expect("should find an element header");
1560        assert_eq!(
1561            header_2,
1562            DataElementHeader {
1563                tag: Tag(0x0028, 0x0120),
1564                vr: VR::SS,
1565                len: Length(2),
1566            }
1567        );
1568    }
1569}