dicom_parser/stateful/
decode.rs

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