Skip to main content

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