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/// 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            .map(|header| {
984                self.position += 8;
985                header
986            })
987    }
988
989    fn read_value(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
990        if header.length() == Length(0) {
991            return Ok(PrimitiveValue::Empty);
992        }
993
994        match header.vr() {
995            VR::SQ => {
996                // sequence objects should not head over here, they are
997                // handled at a higher level
998                NonPrimitiveTypeSnafu {
999                    position: self.position,
1000                }
1001                .fail()
1002            }
1003            VR::AT => self.read_value_tag(header),
1004            VR::AE | VR::AS | VR::PN | VR::SH | VR::LO | VR::UC | VR::UI => {
1005                self.read_value_strs(header)
1006            }
1007            VR::CS => self.read_value_cs(header),
1008            VR::UT | VR::ST | VR::UR | VR::LT => self.read_value_str(header),
1009            VR::UN | VR::OB => self.read_value_ob(header),
1010            VR::US | VR::OW => self.read_value_us(header),
1011            VR::SS => self.read_value_ss(header),
1012            VR::DA => self.read_value_da(header),
1013            VR::DT => self.read_value_dt(header),
1014            VR::TM => self.read_value_tm(header),
1015            VR::DS => self.read_value_ds(header),
1016            VR::FD | VR::OD => self.read_value_od(header),
1017            VR::FL | VR::OF => self.read_value_fl(header),
1018            VR::IS => self.read_value_is(header),
1019            VR::SL => self.read_value_sl(header),
1020            VR::SV => self.read_value_sv(header),
1021            VR::OL | VR::UL => self.read_value_ul(header),
1022            VR::OV | VR::UV => self.read_value_uv(header),
1023        }
1024    }
1025
1026    fn read_value_preserved(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
1027        if header.length() == Length(0) {
1028            return Ok(PrimitiveValue::Empty);
1029        }
1030
1031        match header.vr() {
1032            VR::SQ => {
1033                // sequence objects... should not work
1034                NonPrimitiveTypeSnafu {
1035                    position: self.position,
1036                }
1037                .fail()
1038            }
1039            VR::AT => self.read_value_tag(header),
1040            VR::AE
1041            | VR::AS
1042            | VR::PN
1043            | VR::SH
1044            | VR::LO
1045            | VR::UC
1046            | VR::UI
1047            | VR::IS
1048            | VR::DS
1049            | VR::DA
1050            | VR::TM
1051            | VR::DT => self.read_value_strs(header),
1052            VR::CS => self.read_value_cs(header),
1053            VR::UT | VR::ST | VR::UR | VR::LT => self.read_value_str(header),
1054            VR::UN | VR::OB => self.read_value_ob(header),
1055            VR::US | VR::OW => self.read_value_us(header),
1056            VR::SS => self.read_value_ss(header),
1057            VR::FD | VR::OD => self.read_value_od(header),
1058            VR::FL | VR::OF => self.read_value_fl(header),
1059            VR::SL => self.read_value_sl(header),
1060            VR::OL | VR::UL => self.read_value_ul(header),
1061            VR::SV => self.read_value_sv(header),
1062            VR::OV | VR::UV => self.read_value_uv(header),
1063        }
1064    }
1065
1066    fn read_value_bytes(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue> {
1067        if header.length() == Length(0) {
1068            return Ok(PrimitiveValue::Empty);
1069        }
1070
1071        match header.vr() {
1072            VR::SQ => {
1073                // sequence objects... should not work
1074                NonPrimitiveTypeSnafu {
1075                    position: self.position,
1076                }
1077                .fail()
1078            }
1079            _ => self.read_value_ob(header),
1080        }
1081    }
1082
1083    fn position(&self) -> u64 {
1084        self.position
1085    }
1086
1087    fn read_to_vec(&mut self, length: u32, vec: &mut Vec<u8>) -> Result<()> {
1088        self.read_to(length, vec)
1089    }
1090
1091    fn read_u32_to_vec(&mut self, length: u32, vec: &mut Vec<u32>) -> Result<()> {
1092        self.read_u32((length >> 2) as usize, vec)
1093    }
1094
1095    fn read_to<W>(&mut self, length: u32, mut out: W) -> Result<()>
1096    where
1097        Self: Sized,
1098        W: std::io::Write,
1099    {
1100        let length = u64::from(length);
1101        std::io::copy(&mut self.from.by_ref().take(length), &mut out).context(
1102            ReadValueDataSnafu {
1103                position: self.position,
1104            },
1105        )?;
1106        self.position += length;
1107        Ok(())
1108    }
1109
1110    fn skip_bytes(&mut self, length: u32) -> Result<()> {
1111        std::io::copy(
1112            &mut self.from.by_ref().take(u64::from(length)),
1113            &mut std::io::sink(),
1114        )
1115        .context(ReadValueDataSnafu {
1116            position: self.position,
1117        })?;
1118
1119        self.position += u64::from(length);
1120        Ok(())
1121    }
1122
1123    fn seek(&mut self, position: u64) -> Result<()>
1124    where
1125        Self::Reader: Seek,
1126    {
1127        self.from
1128            .seek(SeekFrom::Start(position))
1129            .context(SeekReaderSnafu {
1130                position: self.position,
1131                new_position: position,
1132            })
1133            .map(|_| ())
1134    }
1135}
1136
1137impl<D, S, BD> StatefulDecoder<D, S, BD>
1138where
1139    D: DecodeFrom<S>,
1140    BD: BasicDecode,
1141    S: Read,
1142{
1143    /// The pixel representation affects the VR for several elements.
1144    /// Returns `Some(VR::SS)` if the vr needs to be modified to SS. Returns `None`
1145    /// if this element is not affected _or_ if we have Unsigned Pixel Representation.
1146    fn determine_vr_based_on_pixel_representation(&self, tag: Tag) -> Option<VR> {
1147        use dicom_core::dictionary::DataDictionary;
1148
1149        if self.signed_pixeldata == Some(true)
1150            && StandardDataDictionary.by_tag(tag).map(|e| e.vr) == Some(VirtualVr::Xs)
1151        {
1152            Some(VR::SS)
1153        } else {
1154            None
1155        }
1156    }
1157}
1158
1159/// Remove trailing spaces and null characters.
1160fn trim_trail_empty_bytes(mut x: &[u8]) -> &[u8] {
1161    while x.last() == Some(&b' ') || x.last() == Some(&b'\0') {
1162        x = &x[..x.len() - 1];
1163    }
1164    x
1165}
1166
1167#[cfg(test)]
1168mod tests {
1169    use super::{StatefulDecode, StatefulDecoder};
1170    use dicom_core::header::{DataElementHeader, HasLength, Header, Length, SequenceItemHeader};
1171    use dicom_core::{Tag, VR};
1172    use dicom_encoding::decode::basic::LittleEndianBasicDecoder;
1173    use dicom_encoding::decode::{
1174        explicit_le::ExplicitVRLittleEndianDecoder, implicit_le::ImplicitVRLittleEndianDecoder,
1175    };
1176    use dicom_encoding::text::{SpecificCharacterSet, TextCodec};
1177    use std::io::{Cursor, Seek, SeekFrom};
1178
1179    // manually crafting some DICOM data elements
1180    //  Tag: (0002,0002) Media Storage SOP Class UID
1181    //  VR: UI
1182    //  Length: 26
1183    //  Value: "1.2.840.10008.5.1.4.1.1.1\0"
1184    // --
1185    //  Tag: (0002,0010) Transfer Syntax UID
1186    //  VR: UI
1187    //  Length: 20
1188    //  Value: "1.2.840.10008.1.2.1\0" == ExplicitVRLittleEndian
1189    // --
1190    const RAW: &[u8; 62] = &[
1191        0x02, 0x00, 0x02, 0x00, 0x55, 0x49, 0x1a, 0x00, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30,
1192        0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e,
1193        0x31, 0x2e, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x55, 0x49, 0x14, 0x00, 0x31, 0x2e, 0x32,
1194        0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x2e,
1195        0x31, 0x00,
1196    ];
1197
1198    fn is_stateful_decoder<T>(_: &T)
1199    where
1200        T: StatefulDecode,
1201    {
1202    }
1203
1204    #[test]
1205    fn decode_data_elements() {
1206        let mut cursor = Cursor::new(&RAW[..]);
1207        let mut decoder = StatefulDecoder::new(
1208            &mut cursor,
1209            ExplicitVRLittleEndianDecoder::default(),
1210            LittleEndianBasicDecoder,
1211            SpecificCharacterSet::default(),
1212        );
1213
1214        is_stateful_decoder(&decoder);
1215
1216        {
1217            // read first element
1218            let elem = decoder.decode_header().expect("should find an element");
1219            assert_eq!(elem.tag(), Tag(2, 2));
1220            assert_eq!(elem.vr(), VR::UI);
1221            assert_eq!(elem.length(), Length(26));
1222
1223            assert_eq!(decoder.position(), 8);
1224
1225            // read value
1226            let value = decoder
1227                .read_value(&elem)
1228                .expect("value after element header");
1229            assert_eq!(value.multiplicity(), 1);
1230            assert_eq!(value.string(), Ok("1.2.840.10008.5.1.4.1.1.1\0"));
1231
1232            assert_eq!(decoder.position(), 8 + 26);
1233        }
1234        {
1235            // read second element
1236            let elem = decoder.decode_header().expect("should find an element");
1237            assert_eq!(elem.tag(), Tag(2, 16));
1238            assert_eq!(elem.vr(), VR::UI);
1239            assert_eq!(elem.length(), Length(20));
1240
1241            assert_eq!(decoder.position(), 8 + 26 + 8);
1242
1243            // read value
1244            let value = decoder
1245                .read_value(&elem)
1246                .expect("value after element header");
1247            assert_eq!(value.multiplicity(), 1);
1248            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1249
1250            assert_eq!(decoder.position(), 8 + 26 + 8 + 20);
1251
1252            // rolling back to read the last value again
1253            decoder.seek(8 + 26 + 8).unwrap();
1254
1255            // read value
1256            let value = decoder
1257                .read_value(&elem)
1258                .expect("value after element header");
1259            assert_eq!(value.multiplicity(), 1);
1260            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1261
1262            assert_eq!(decoder.position(), 8 + 26 + 8 + 20 + 20);
1263        }
1264    }
1265
1266    /// Test that the stateful decoder updates
1267    /// the active character set after reaching a Specific Character Set element
1268    /// with a supported text encoding.
1269    #[test]
1270    fn update_character_set() {
1271        const RAW: &[u8; 18] = &[
1272            // Tag: (0008,0005) Specific Character Set
1273            0x08, 0x00, 0x05, 0x00, // VR: CS
1274            b'C', b'S', // Length: 10
1275            0x0a, 0x00, // Value: "ISO_IR 192"
1276            b'I', b'S', b'O', b'_', b'I', b'R', b' ', b'1', b'9', b'2',
1277        ];
1278
1279        let mut cursor = &RAW[..];
1280        let mut decoder = StatefulDecoder::new(
1281            &mut cursor,
1282            ExplicitVRLittleEndianDecoder::default(),
1283            LittleEndianBasicDecoder,
1284            SpecificCharacterSet::default(),
1285        );
1286
1287        is_stateful_decoder(&decoder);
1288
1289        let header = decoder
1290            .decode_header()
1291            .expect("should find an element header");
1292        assert_eq!(
1293            header,
1294            DataElementHeader {
1295                tag: Tag(0x0008, 0x0005),
1296                vr: VR::CS,
1297                len: Length(10),
1298            }
1299        );
1300
1301        let value = decoder
1302            .read_value_preserved(&header)
1303            .expect("should read a value");
1304
1305        assert_eq!(value.string(), Ok("ISO_IR 192"));
1306        assert_eq!(decoder.text.name(), "ISO_IR 192",);
1307    }
1308
1309    #[test]
1310    fn decode_data_elements_with_position() {
1311        let data = {
1312            let mut x = vec![0; 128];
1313            x.extend(RAW);
1314            x
1315        };
1316
1317        // have cursor start 128 bytes ahead
1318        let mut cursor = Cursor::new(&data[..]);
1319        cursor.seek(SeekFrom::Start(128)).unwrap();
1320
1321        let mut decoder = StatefulDecoder::new_with_position(
1322            &mut cursor,
1323            ExplicitVRLittleEndianDecoder::default(),
1324            LittleEndianBasicDecoder,
1325            SpecificCharacterSet::default(),
1326            128,
1327        );
1328
1329        is_stateful_decoder(&decoder);
1330
1331        {
1332            // read first element
1333            let elem = decoder.decode_header().expect("should find an element");
1334            assert_eq!(elem.tag(), Tag(2, 2));
1335            assert_eq!(elem.vr(), VR::UI);
1336            assert_eq!(elem.length(), Length(26));
1337
1338            assert_eq!(decoder.position(), 128 + 8);
1339
1340            // read value
1341            let value = decoder
1342                .read_value(&elem)
1343                .expect("value after element header");
1344            assert_eq!(value.multiplicity(), 1);
1345            assert_eq!(value.string(), Ok("1.2.840.10008.5.1.4.1.1.1\0"));
1346
1347            assert_eq!(decoder.position(), 128 + 8 + 26);
1348        }
1349        {
1350            // read second element
1351            let elem = decoder.decode_header().expect("should find an element");
1352            assert_eq!(elem.tag(), Tag(2, 16));
1353            assert_eq!(elem.vr(), VR::UI);
1354            assert_eq!(elem.length(), Length(20));
1355
1356            assert_eq!(decoder.position(), 128 + 8 + 26 + 8);
1357
1358            // read value
1359            let value = decoder
1360                .read_value(&elem)
1361                .expect("value after element header");
1362            assert_eq!(value.multiplicity(), 1);
1363            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1364
1365            assert_eq!(decoder.position(), 128 + 8 + 26 + 8 + 20);
1366
1367            // rolling back to read the last value again
1368            decoder.seek(128 + 8 + 26 + 8).unwrap();
1369
1370            // read value
1371            let value = decoder
1372                .read_value(&elem)
1373                .expect("value after element header");
1374            assert_eq!(value.multiplicity(), 1);
1375            assert_eq!(value.string(), Ok("1.2.840.10008.1.2.1\0"));
1376
1377            assert_eq!(decoder.position(), 128 + 8 + 26 + 8 + 20 + 20);
1378        }
1379    }
1380
1381    #[test]
1382    fn decode_nested_datasets() {
1383        const RAW: &[u8; 138] = &[
1384            // 0: (2001, 9000) private sequence
1385            0x01, 0x20, 0x00, 0x90, //
1386            // length: undefined
1387            0xFF, 0xFF, 0xFF, 0xFF, //
1388            // 8: Item start
1389            0xFE, 0xFF, 0x00, 0xE0, //
1390            // Item length explicit (114)
1391            0x72, 0x00, 0x00, 0x00, //
1392            // 16: (0008,1115) ReferencedSeriesSequence
1393            0x08, 0x00, 0x15, 0x11, //
1394            // length: undefined
1395            0xFF, 0xFF, 0xFF, 0xFF, //
1396            // 24: Item start
1397            0xFE, 0xFF, 0x00, 0xE0, //
1398            // Item length undefined
1399            0xFF, 0xFF, 0xFF, 0xFF, //
1400            // 32: (0008,1140) ReferencedImageSequence
1401            0x08, 0x00, 0x40, 0x11, //
1402            // length: undefined
1403            0xFF, 0xFF, 0xFF, 0xFF, //
1404            // 40: Item start
1405            0xFE, 0xFF, 0x00, 0xE0, //
1406            // Item length undefined
1407            0xFF, 0xFF, 0xFF, 0xFF, //
1408            // 48: (0008,1150) ReferencedSOPClassUID
1409            0x08, 0x00, 0x50, 0x11, //
1410            // length: 26
1411            0x1a, 0x00, 0x00, 0x00, //
1412            // Value: "1.2.840.10008.5.1.4.1.1.7\0" (SecondaryCaptureImageStorage)
1413            b'1', b'.', b'2', b'.', b'8', b'4', b'0', b'.', b'1', b'0', b'0', b'0', b'8', b'.',
1414            b'5', b'.', b'1', b'.', b'4', b'.', b'1', b'.', b'1', b'.', b'7', b'\0',
1415            // 82: Item End (ReferencedImageSequence)
1416            0xFE, 0xFF, 0x0D, 0xE0, //
1417            0x00, 0x00, 0x00, 0x00, //
1418            // 90: Sequence End (ReferencedImageSequence)
1419            0xFE, 0xFF, 0xDD, 0xE0, //
1420            0x00, 0x00, 0x00, 0x00, //
1421            // 98: Item End (ReferencedSeriesSequence)
1422            0xFE, 0xFF, 0x0D, 0xE0, //
1423            0x00, 0x00, 0x00, 0x00, //
1424            // 106: Sequence End (ReferencedSeriesSequence)
1425            0xFE, 0xFF, 0xDD, 0xE0, //
1426            0x00, 0x00, 0x00, 0x00, //
1427            // 114: (2050,0020) PresentationLUTShape (CS)
1428            0x50, 0x20, 0x20, 0x00, //
1429            // length: 8
1430            0x08, 0x00, 0x00, 0x00, //
1431            b'I', b'D', b'E', b'N', b'T', b'I', b'T', b'Y', // 130: Sequence end
1432            0xFE, 0xFF, 0xDD, 0xE0, //
1433            0x00, 0x00, 0x00, 0x00, //
1434        ];
1435
1436        let mut cursor = &RAW[..];
1437        let mut decoder = StatefulDecoder::new(
1438            &mut cursor,
1439            ImplicitVRLittleEndianDecoder::default(),
1440            LittleEndianBasicDecoder,
1441            SpecificCharacterSet::default(),
1442        );
1443
1444        is_stateful_decoder(&decoder);
1445
1446        let header = decoder
1447            .decode_header()
1448            .expect("should find an element header");
1449        assert_eq!(header.tag(), Tag(0x2001, 0x9000));
1450        assert_eq!(header.vr(), VR::UN);
1451        assert!(header.length().is_undefined());
1452
1453        assert_eq!(decoder.position(), 8);
1454
1455        let item_header = decoder
1456            .decode_item_header()
1457            .expect("should find an item header");
1458        assert_eq!(item_header, SequenceItemHeader::Item { len: Length(114) });
1459
1460        assert_eq!(decoder.position(), 16);
1461
1462        // enter ReferencedSeriesSequence
1463        let header = decoder
1464            .decode_header()
1465            .expect("should find an element header");
1466        assert_eq!(header.tag(), Tag(0x0008, 0x1115));
1467        assert_eq!(header.vr(), VR::SQ);
1468        assert!(header.length().is_undefined());
1469
1470        assert_eq!(decoder.position(), 24);
1471
1472        let item_header = decoder
1473            .decode_item_header()
1474            .expect("should find an item header (ReferencedSeriesSequence)");
1475        assert!(matches!(
1476            item_header,
1477            SequenceItemHeader::Item {
1478                len,
1479            } if len.is_undefined()
1480        ));
1481
1482        assert_eq!(decoder.position(), 32);
1483
1484        // enter ReferencedImageSequence
1485        let header = decoder
1486            .decode_header()
1487            .expect("should find an element header");
1488        assert_eq!(header.tag(), Tag(0x0008, 0x1140));
1489        assert_eq!(header.vr(), VR::SQ);
1490        assert!(header.length().is_undefined());
1491
1492        assert_eq!(decoder.position(), 40);
1493
1494        let item_header = decoder
1495            .decode_item_header()
1496            .expect("should find an item header (ReferencedImageSequence)");
1497        assert!(matches!(
1498            item_header,
1499            SequenceItemHeader::Item {
1500                len,
1501            } if len.is_undefined()
1502        ));
1503
1504        assert_eq!(decoder.position(), 48);
1505
1506        // read ReferencedSOPClassUID
1507
1508        let header = decoder
1509            .decode_header()
1510            .expect("should find an element header");
1511        assert_eq!(header.tag(), Tag(0x0008, 0x1150));
1512        assert_eq!(header.vr(), VR::UI);
1513        assert_eq!(header.length(), Length(26));
1514
1515        assert_eq!(decoder.position(), 56);
1516
1517        let value = decoder
1518            .read_value(&header)
1519            .expect("should find a value after element header");
1520        assert_eq!(value.to_str(), "1.2.840.10008.5.1.4.1.1.7");
1521
1522        assert_eq!(decoder.position(), 82);
1523
1524        // exit ReferencedImageSequence
1525
1526        let item_header = decoder
1527            .decode_item_header()
1528            .expect("should find item delimiter");
1529        assert_eq!(item_header, SequenceItemHeader::ItemDelimiter);
1530
1531        assert_eq!(decoder.position(), 90);
1532
1533        let item_header = decoder
1534            .decode_item_header()
1535            .expect("should find sequence delimiter");
1536        assert_eq!(item_header, SequenceItemHeader::SequenceDelimiter);
1537
1538        assert_eq!(decoder.position(), 98);
1539
1540        // exit ReferencedSeriesSequence
1541
1542        let item_header = decoder
1543            .decode_item_header()
1544            .expect("should find item delimiter");
1545        assert_eq!(item_header, SequenceItemHeader::ItemDelimiter);
1546
1547        assert_eq!(decoder.position(), 106);
1548
1549        let item_header = decoder
1550            .decode_item_header()
1551            .expect("should find sequence delimiter");
1552        assert_eq!(item_header, SequenceItemHeader::SequenceDelimiter);
1553
1554        assert_eq!(decoder.position(), 114);
1555
1556        // read PresentationLUTShape
1557
1558        let header = decoder
1559            .decode_header()
1560            .expect("should find an element header");
1561        assert_eq!(header.tag(), Tag(0x2050, 0x0020));
1562        assert_eq!(header.vr(), VR::CS);
1563        assert_eq!(header.length(), Length(8));
1564
1565        assert_eq!(decoder.position(), 122);
1566
1567        let value = decoder
1568            .read_value(&header)
1569            .expect("value after element header");
1570        assert_eq!(value.multiplicity(), 1);
1571        assert_eq!(value.to_str(), "IDENTITY");
1572
1573        assert_eq!(decoder.position(), 130);
1574
1575        // exit private sequence
1576        // (no item delimiter because length is explicit)
1577
1578        let item_header = decoder
1579            .decode_item_header()
1580            .expect("should find an item header");
1581        assert_eq!(item_header, SequenceItemHeader::SequenceDelimiter);
1582
1583        assert_eq!(decoder.position(), 138);
1584    }
1585
1586    #[test]
1587    fn decode_and_use_pixel_representation() {
1588        const RAW: &[u8; 20] = &[
1589            0x28, 0x00, 0x03, 0x01, // Tag: (0023,0103) PixelRepresentation
1590            0x02, 0x00, 0x00, 0x00, // Length: 2
1591            0x01, 0x00, // Value: "1",
1592            0x28, 0x00, 0x20, 0x01, // Tag: (0023,0120) PixelPadding
1593            0x02, 0x00, 0x00, 0x00, // Length: 2
1594            0x01, 0x00, // Value: "1"
1595        ];
1596
1597        let mut cursor = &RAW[..];
1598        let mut decoder = StatefulDecoder::new(
1599            &mut cursor,
1600            ImplicitVRLittleEndianDecoder::default(),
1601            LittleEndianBasicDecoder,
1602            SpecificCharacterSet::default(),
1603        );
1604
1605        is_stateful_decoder(&decoder);
1606
1607        let header_1 = decoder
1608            .decode_header()
1609            .expect("should find an element header");
1610        assert_eq!(
1611            header_1,
1612            DataElementHeader {
1613                tag: Tag(0x0028, 0x0103),
1614                vr: VR::US,
1615                len: Length(2),
1616            }
1617        );
1618
1619        decoder
1620            .read_value(&header_1)
1621            .expect("Can read Pixel Representation");
1622
1623        let header_2 = decoder
1624            .decode_header()
1625            .expect("should find an element header");
1626        assert_eq!(
1627            header_2,
1628            DataElementHeader {
1629                tag: Tag(0x0028, 0x0120),
1630                vr: VR::SS,
1631                len: Length(2),
1632            }
1633        );
1634    }
1635
1636    #[test]
1637    fn decode_text_with_charset_override() {
1638        #[rustfmt::skip]
1639        const RAW: &[u8; 28] = &[
1640            // Tag: (0018,0015) Body Part Examined
1641            0x18, 0x00, 0x15, 0x00,
1642            // VR: CS
1643            b'C', b'S',
1644            // Length: 20
1645            0x14, 0x00, // Value: "脊柱侧弯-视图" (scoliosis-view)
1646            232, 132, 138, 230, 159, 177, 228, 190,
1647            167, 229, 188, 175, 45, 232, 167, 134,
1648            229, 155, 190, b' '
1649        ];
1650
1651        let mut cursor = &RAW[..];
1652
1653        let mut decoder = StatefulDecoder::new_with_all_options(
1654            &mut cursor,
1655            ExplicitVRLittleEndianDecoder::default(),
1656            LittleEndianBasicDecoder,
1657            SpecificCharacterSet::ISO_IR_192,
1658            // use AnyVr so that Body Part Examined
1659            super::CharacterSetOverride::AnyVr,
1660            0,
1661        );
1662
1663        is_stateful_decoder(&decoder);
1664
1665        let header_1 = decoder
1666            .decode_header()
1667            .expect("should find an element header");
1668        assert_eq!(
1669            header_1,
1670            DataElementHeader {
1671                tag: Tag(0x0018, 0x0015),
1672                vr: VR::CS,
1673                len: Length(20),
1674            }
1675        );
1676
1677        let val = decoder
1678            .read_value(&header_1)
1679            .expect("Can read Body Part Examined");
1680
1681        assert_eq!(val.to_str(), "脊柱侧弯-视图",);
1682    }
1683}