1use 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 fn decode_header(&mut self) -> Result<DataElementHeader>;
141
142 fn decode_item_header(&mut self) -> Result<SequenceItemHeader>;
144
145 fn read_value(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue>;
158
159 fn read_value_preserved(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue>;
169
170 fn read_value_bytes(&mut self, header: &DataElementHeader) -> Result<PrimitiveValue>;
178
179 fn read_to_vec(&mut self, length: u32, vec: &mut Vec<u8>) -> Result<()>;
181
182 fn read_u32_to_vec(&mut self, length: u32, vec: &mut Vec<u32>) -> Result<()>;
186
187 fn read_to<W>(&mut self, length: u32, out: W) -> Result<()>
189 where
190 Self: Sized,
191 W: std::io::Write;
192
193 fn skip_bytes(&mut self, length: u32) -> Result<()>;
196
197 fn seek(&mut self, position: u64) -> Result<()>
202 where
203 Self::Reader: Seek;
204
205 fn position(&self) -> u64;
209}
210
211pub type DynStatefulDecoder<S> = StatefulDecoder<DynDecoder<S>, S>;
215
216const PARSER_BUFFER_CAPACITY: usize = 2048;
218
219#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
222#[non_exhaustive]
223pub enum CharacterSetOverride {
224 #[default]
230 None,
231
232 AnyVr,
238}
239
240#[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 position: u64,
258 signed_pixeldata: Option<bool>,
259}
260
261impl<S> StatefulDecoder<DynDecoder<S>, S> {
262 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 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 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
323pub type FileHeaderParser<S> = StatefulDecoder<
325 ExplicitVRLittleEndianDecoder,
326 S,
327 LittleEndianBasicDecoder,
328 DefaultCharacterSetCodec,
329>;
330
331impl<S> FileHeaderParser<S>
332where
333 S: Read,
334{
335 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 #[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 #[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 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 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 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 let len = self.require_known_length(header)?;
458
459 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 header.tag == Tag(0x0008, 0x0005) {
873 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 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 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 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 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 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
1159fn 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 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 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 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 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 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 decoder.seek(8 + 26 + 8).unwrap();
1254
1255 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]
1270 fn update_character_set() {
1271 const RAW: &[u8; 18] = &[
1272 0x08, 0x00, 0x05, 0x00, b'C', b'S', 0x0a, 0x00, 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 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 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 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 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 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 decoder.seek(128 + 8 + 26 + 8).unwrap();
1369
1370 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 0x01, 0x20, 0x00, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0x72, 0x00, 0x00, 0x00, 0x08, 0x00, 0x15, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x40, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x50, 0x11, 0x1a, 0x00, 0x00, 0x00, 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 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xDD, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x0D, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xDD, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, b'I', b'D', b'E', b'N', b'T', b'I', b'T', b'Y', 0xFE, 0xFF, 0xDD, 0xE0, 0x00, 0x00, 0x00, 0x00, ];
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 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 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 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 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 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 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 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, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, ];
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 0x18, 0x00, 0x15, 0x00,
1642 b'C', b'S',
1644 0x14, 0x00, 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 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}