1use crate::encode::basic::BigEndianBasicEncoder;
4use crate::encode::{
5 BasicEncode, Encode, Result, WriteHeaderSnafu, WriteHeaderTooLongSnafu,
6 WriteItemDelimiterSnafu, WriteItemHeaderSnafu, WriteOffsetTableSnafu,
7 WriteSequenceDelimiterSnafu, WriteTagSnafu,
8};
9
10use byteordered::Endianness;
11use byteordered::byteorder::{BigEndian, ByteOrder};
12use dicom_core::header::{DataElementHeader, HasLength, Header};
13use dicom_core::{PrimitiveValue, Tag, VR};
14use snafu::ResultExt;
15use std::io::{self, Write};
16
17#[derive(Debug, Default, Clone)]
19pub struct ExplicitVRBigEndianEncoder {
20 basic: BigEndianBasicEncoder,
21}
22
23impl BasicEncode for ExplicitVRBigEndianEncoder {
24 fn endianness(&self) -> Endianness {
25 Endianness::Big
26 }
27
28 fn encode_us<S>(&self, to: S, value: u16) -> io::Result<()>
29 where
30 S: Write,
31 {
32 self.basic.encode_us(to, value)
33 }
34
35 fn encode_ul<S>(&self, to: S, value: u32) -> io::Result<()>
36 where
37 S: Write,
38 {
39 self.basic.encode_ul(to, value)
40 }
41
42 fn encode_uv<S>(&self, to: S, value: u64) -> io::Result<()>
43 where
44 S: Write,
45 {
46 self.basic.encode_uv(to, value)
47 }
48
49 fn encode_ss<S>(&self, to: S, value: i16) -> io::Result<()>
50 where
51 S: Write,
52 {
53 self.basic.encode_ss(to, value)
54 }
55
56 fn encode_sl<S>(&self, to: S, value: i32) -> io::Result<()>
57 where
58 S: Write,
59 {
60 self.basic.encode_sl(to, value)
61 }
62
63 fn encode_sv<S>(&self, to: S, value: i64) -> io::Result<()>
64 where
65 S: Write,
66 {
67 self.basic.encode_sv(to, value)
68 }
69
70 fn encode_fl<S>(&self, to: S, value: f32) -> io::Result<()>
71 where
72 S: Write,
73 {
74 self.basic.encode_fl(to, value)
75 }
76
77 fn encode_fd<S>(&self, to: S, value: f64) -> io::Result<()>
78 where
79 S: Write,
80 {
81 self.basic.encode_fd(to, value)
82 }
83}
84
85impl Encode for ExplicitVRBigEndianEncoder {
86 fn encode_tag<W>(&self, mut to: W, tag: Tag) -> Result<()>
87 where
88 W: Write,
89 {
90 let mut buf = [0u8; 4];
91 BigEndian::write_u16(&mut buf[..], tag.group());
92 BigEndian::write_u16(&mut buf[2..], tag.element());
93 to.write_all(&buf).context(WriteTagSnafu)
94 }
95
96 fn encode_element_header<W>(&self, mut to: W, de: DataElementHeader) -> Result<usize>
97 where
98 W: Write,
99 {
100 match de.vr() {
101 VR::AE
108 | VR::AS
109 | VR::AT
110 | VR::CS
111 | VR::DA
112 | VR::DS
113 | VR::DT
114 | VR::FL
115 | VR::FD
116 | VR::IS
117 | VR::LO
118 | VR::LT
119 | VR::PN
120 | VR::SH
121 | VR::SL
122 | VR::SS
123 | VR::ST
124 | VR::TM
125 | VR::UI
126 | VR::UL
127 | VR::US => {
128 let length = de.length().0;
129 if length > u16::MAX as u32 {
130 return WriteHeaderTooLongSnafu { length }.fail();
131 }
132 let mut buf = [0u8; 8];
133 BigEndian::write_u16(&mut buf[0..], de.tag().group());
134 BigEndian::write_u16(&mut buf[2..], de.tag().element());
135 let vr_bytes = de.vr().to_bytes();
136 buf[4] = vr_bytes[0];
137 buf[5] = vr_bytes[1];
138 BigEndian::write_u16(&mut buf[6..], length as u16);
139 to.write_all(&buf).context(WriteHeaderSnafu)?;
140
141 Ok(8)
142 }
143 _ => {
150 let mut buf = [0u8; 12];
151 BigEndian::write_u16(&mut buf[0..], de.tag().group());
152 BigEndian::write_u16(&mut buf[2..], de.tag().element());
153 let vr_bytes = de.vr().to_bytes();
154 buf[4] = vr_bytes[0];
155 buf[5] = vr_bytes[1];
156 BigEndian::write_u32(&mut buf[8..], de.length().0);
158 to.write_all(&buf).context(WriteHeaderSnafu)?;
159
160 Ok(12)
161 }
162 }
163 }
164
165 fn encode_item_header<W>(&self, mut to: W, len: u32) -> Result<()>
166 where
167 W: Write,
168 {
169 let mut buf = [0u8; 8];
170 BigEndian::write_u16(&mut buf, 0xFFFE);
171 BigEndian::write_u16(&mut buf[2..], 0xE000);
172 BigEndian::write_u32(&mut buf[4..], len);
173 to.write_all(&buf).context(WriteItemHeaderSnafu)
174 }
175
176 fn encode_item_delimiter<W>(&self, mut to: W) -> Result<()>
177 where
178 W: Write,
179 {
180 let mut buf = [0u8; 8];
181 BigEndian::write_u16(&mut buf, 0xFFFE);
182 BigEndian::write_u16(&mut buf[2..], 0xE00D);
183 to.write_all(&buf).context(WriteItemDelimiterSnafu)
185 }
186
187 fn encode_sequence_delimiter<W>(&self, mut to: W) -> Result<()>
188 where
189 W: Write,
190 {
191 let mut buf = [0u8; 8];
192 BigEndian::write_u16(&mut buf, 0xFFFE);
193 BigEndian::write_u16(&mut buf[2..], 0xE0DD);
194 to.write_all(&buf).context(WriteSequenceDelimiterSnafu)
196 }
197
198 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
199 where
200 W: Write,
201 {
202 self.basic.encode_primitive(to, value)
203 }
204
205 fn encode_offset_table<W>(&self, mut to: W, offset_table: &[u32]) -> Result<usize>
206 where
207 W: Write,
208 {
209 for v in offset_table {
210 self.basic
211 .encode_ul(&mut to, *v)
212 .context(WriteOffsetTableSnafu)?;
213 }
214 Ok(offset_table.len() * 4)
215 }
216}
217
218#[cfg(test)]
219mod tests {
220 use super::ExplicitVRBigEndianEncoder;
221 use crate::encode::Encode;
222 use dicom_core::header::{DataElementHeader, Length};
223 use dicom_core::{Tag, VR};
224 use std::io::{Cursor, Write};
225
226 type Result = std::result::Result<(), Box<dyn std::error::Error>>;
227
228 #[rustfmt::skip]
230 const RAW: &[u8] = &[
231 0x00, 0x02, 0x00, 0x02, b'U', b'I', 0x00, 0x1A, b'1', b'.', b'2', b'.', b'8', b'4', b'0', b'.', b'1', b'0', b'0', b'0', b'8', b'.',
236 b'5', b'.', b'1', b'.', b'4', b'.', b'1', b'.', b'1', b'.', b'1',
237 0x00, 0x00, 0x02, 0x00, 0x10, b'U', b'I', 0x00, 0x14, b'1', b'.', b'2', b'.', b'8', b'4', b'0', b'.', b'1', b'0', b'0', b'0', b'8', b'.',
243 b'1', b'.', b'2', b'.', b'1',
244 0x00, 0x00, 0x08, 0x00, 0x54, b'A', b'E', 0x00, 0x06, b'T', b'I', b'T', b'L', b'E',
250 b' ', 0x00, 0x10, 0x10, 0x10, b'A', b'S', 0x00, 0x02, b'8', b'Y',
256 0x00, 0x72, 0x00, 0x26, b'A', b'T', 0x00, 0x04, 0x00, 0x28, 0x21, 0x10,
261 0x00, 0x10, 0x00, 0x40, b'C', b'S', 0x00, 0x02, b'O',
266 b' ', 0x00, 0x10, 0x00, 0x30, b'D', b'A', 0x00, 0x08, b'1', b'9', b'8', b'0', b'0', b'1', b'0', b'1',
272 0x00, 0x10, 0x10, 0x20, b'D', b'S', 0x00, 0x04, b'1', b'.', b'7', b'0',
277 0x00, 0x08, 0x00, 0x15, b'D', b'T', 0x00, 0x0E, b'2', b'0', b'0', b'5', b'1', b'2', b'3', b'1', b'2', b'3', b'5', b'9', b'6', b'0',
282 0x00, 0x10, 0x94, 0x31, b'F', b'L', 0x00, 0x04, 0x40, 0x49, 0x0F, 0xDB,
287 0x00, 0x40, 0x92, 0x25, b'F', b'D', 0x00, 0x08, 0x40, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18,
292 0x00, 0x20, 0x00, 0x13, b'I', b'S', 0x00, 0x08, b'1', b'2', b'3', b'4', b'5', b'6', b'7',
297 b' ', 0x00, 0x10, 0x00, 0x20, b'L', b'O', 0x00, 0x0A, b'P', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'X',
303 0x00, 0x10, 0x40, 0x00, b'L', b'T', 0x00, 0x04, b'N', b'o', b'n', b'e',
308 0x00, 0x08, 0x04, 0x1B, b'O', b'B', 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x34,
314 0x7F, 0xE0, 0x00, 0x09, b'O', b'D', 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18,
320 0x7F, 0xE0, 0x00, 0x08, b'O', b'F', 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x49, 0x0F, 0xDB,
326 0x00, 0x72, 0x00, 0x75, b'O', b'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78,
332 0x00, 0x72, 0x00, 0x81, b'O', b'V', 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x2A, 0x3B, 0x4C, 0x5D, 0x6E, 0x7F, 0x80,
338 0x00, 0x72, 0x00, 0x69, b'O', b'W', 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x34,
344 0x00, 0x10, 0x00, 0x10, b'P', b'N', 0x00, 0x08, b'D', b'o', b'e', b'^', b'J', b'o', b'h', b'n',
349 0x00, 0x40, 0x92, 0x10, b'S', b'H', 0x00, 0x04, b'L', b'B', b'L',
354 b' ', 0x00, 0x18, 0x60, 0x20, b'S', b'L', 0x00, 0x04, 0xFF, 0x43, 0x9E, 0xB2,
360 0x00, 0x28, 0x95, 0x03, b'S', b'S', 0x00, 0x04, 0xEE, 0x29,
366 0x10, 0xE1,
368 0x00, 0x40, 0x02, 0x80, b'S', b'T', 0x00, 0x0A, b'N', b'o', b' ', b'c', b'o', b'm', b'm', b'e', b'n', b't',
373 0x00, 0x72, 0x00, 0x82, b'S', b'V', 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xFE, 0x49, 0x64, 0xB4, 0x59, 0xCF, 0x0C, 0xB2,
379 0x01, 0xB6, 0x9B, 0x4B, 0xA6, 0x30, 0xF3, 0x4E,
381 0x00, 0x10, 0x00, 0x32, b'T', b'M', 0x00, 0x06, b'1', b'2', b'3', b'4', b'5', b'6',
386 0x00, 0x08, 0x01, 0x19, b'U', b'C', 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, b'C', b'o', b'd', b'e',
392 0x00, 0x18, 0x60, 0x16, b'U', b'L',
395 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
398 0xC0, 0x01, 0x12, 0x34, b'U', b'N', 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
404 0x00, 0x08, 0x01, 0x0E, b'U', b'R', 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, b'h', b't', b't', b'p', b':', b'/', b'/', b'e', b'x', b'a', b'm', b'p', b'l', b'e',
410 b'.', b'c', b'o', b'm',
411 0x00, 0x08, 0x00, 0x40, b'U', b'S', 0x00, 0x02, 0x87, 0x07,
416 0x00, 0x18, 0x99, 0x17, b'U', b'T', 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, b'N', b'o', b' ', b't', b'e', b'x', b't',
422 b' ', 0x00, 0x08, 0x04, 0x0C, b'U', b'V', 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xAB, 0x54, 0xA9, 0x8C, 0xEB, 0x1F, 0x0A, 0xD2,
429 ];
430
431 #[test]
432 fn encode_explicit_vr_be() {
433 let mut buf = vec![0u8; RAW.len()];
434
435 let enc = ExplicitVRBigEndianEncoder::default();
436 let mut writer = Cursor::new(&mut buf);
437
438 let de = DataElementHeader::new(Tag(0x0002, 0x0002), VR::UI, Length(26));
440 let len = enc
441 .encode_element_header(&mut writer, de)
442 .expect("should write it fine");
443 assert_eq!(len, 8);
444 writer
445 .write_all(b"1.2.840.10008.5.1.4.1.1.1\0".as_ref())
446 .expect("should write the value fine");
447
448 let de = DataElementHeader::new(Tag(0x0002, 0x0010), VR::UI, Length(20));
450 let len = enc
451 .encode_element_header(&mut writer, de)
452 .expect("should write it fine");
453 assert_eq!(len, 8);
454 writer
455 .write_all(b"1.2.840.10008.1.2.1\0".as_ref())
456 .expect("should write the value fine");
457
458 fn write_elem(
459 enc: &ExplicitVRBigEndianEncoder,
460 mut writer: &mut Cursor<&mut Vec<u8>>,
461 group: u16,
462 element: u16,
463 vr: VR,
464 value: &[u8],
465 ) {
466 let from = writer.position() as usize;
467 let de = DataElementHeader::new(Tag(group, element), vr, Length(value.len() as u32));
468 let _written_len = enc
469 .encode_element_header(&mut writer, de)
470 .expect("should write it fine");
471 writer
472 .write_all(value)
473 .expect("should write the value fine");
474 let to = writer.position() as usize;
475
476 if &writer.get_ref()[from..to] != &RAW[from..to] {
478 panic!(
479 "Failure on ({:04x},{:04x}) {:?} {:02x?}\n\
480 Expected: {:02x?}",
481 group,
482 element,
483 vr,
484 value,
485 &RAW[from..to],
486 );
487 }
488 }
489
490 write_elem(&enc, &mut writer, 0x0008, 0x0054, VR::AE, b"TITLE ");
491 write_elem(&enc, &mut writer, 0x0010, 0x1010, VR::AS, b"8Y");
492 write_elem(
493 &enc,
494 &mut writer,
495 0x0072,
496 0x0026,
497 VR::AT,
498 &[0x00, 0x28, 0x21, 0x10],
499 );
500 write_elem(&enc, &mut writer, 0x0010, 0x0040, VR::CS, b"O ");
501 write_elem(&enc, &mut writer, 0x0010, 0x0030, VR::DA, b"19800101");
502 write_elem(&enc, &mut writer, 0x0010, 0x1020, VR::DS, b"1.70");
503 write_elem(&enc, &mut writer, 0x0008, 0x0015, VR::DT, b"20051231235960");
504 write_elem(
505 &enc,
506 &mut writer,
507 0x0010,
508 0x9431,
509 VR::FL,
510 &[0x40, 0x49, 0x0F, 0xDB],
511 );
512 write_elem(
513 &enc,
514 &mut writer,
515 0x0040,
516 0x9225,
517 VR::FD,
518 &[0x40, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18],
519 );
520 write_elem(&enc, &mut writer, 0x0020, 0x0013, VR::IS, b"1234567 ");
521 write_elem(&enc, &mut writer, 0x0010, 0x0020, VR::LO, b"P12345678X");
522 write_elem(&enc, &mut writer, 0x0010, 0x4000, VR::LT, b"None");
523 write_elem(&enc, &mut writer, 0x0008, 0x041B, VR::OB, &[0x12, 0x34]);
524 write_elem(
525 &enc,
526 &mut writer,
527 0x7FE0,
528 0x0009,
529 VR::OD,
530 &[0x40, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18],
531 );
532 write_elem(
533 &enc,
534 &mut writer,
535 0x7FE0,
536 0x0008,
537 VR::OF,
538 &[0x40, 0x49, 0x0F, 0xDB],
539 );
540 write_elem(
541 &enc,
542 &mut writer,
543 0x0072,
544 0x0075,
545 VR::OL,
546 &[0x12, 0x34, 0x56, 0x78],
547 );
548 write_elem(
549 &enc,
550 &mut writer,
551 0x0072,
552 0x0081,
553 VR::OV,
554 &[0x19, 0x2A, 0x3B, 0x4C, 0x5D, 0x6E, 0x7F, 0x80],
555 );
556 write_elem(&enc, &mut writer, 0x0072, 0x0069, VR::OW, &[0x12, 0x34]);
557 write_elem(&enc, &mut writer, 0x0010, 0x0010, VR::PN, b"Doe^John");
558 write_elem(&enc, &mut writer, 0x0040, 0x9210, VR::SH, b"LBL ");
559 write_elem(
560 &enc,
561 &mut writer,
562 0x0018,
563 0x6020,
564 VR::SL,
565 &[0xFF, 0x43, 0x9E, 0xB2],
566 );
567 write_elem(
568 &enc,
569 &mut writer,
570 0x0028,
571 0x9503,
572 VR::SS,
573 &[0xEE, 0x29, 0x10, 0xE1],
574 );
575 write_elem(&enc, &mut writer, 0x0040, 0x0280, VR::ST, b"No comment");
576 write_elem(
577 &enc,
578 &mut writer,
579 0x0072,
580 0x0082,
581 VR::SV,
582 &[
583 0xFE, 0x49, 0x64, 0xB4, 0x59, 0xCF, 0x0C, 0xB2, 0x01, 0xB6, 0x9B, 0x4B, 0xA6, 0x30,
584 0xF3, 0x4E,
585 ],
586 );
587 write_elem(&enc, &mut writer, 0x0010, 0x0032, VR::TM, b"123456");
588 write_elem(&enc, &mut writer, 0x0008, 0x0119, VR::UC, b"Code");
589 write_elem(
590 &enc,
591 &mut writer,
592 0x0018,
593 0x6016,
594 VR::UL,
595 &[0x00, 0x00, 0x00, 0x01],
596 );
597 write_elem(
598 &enc,
599 &mut writer,
600 0xC001,
601 0x1234,
602 VR::UN,
603 &[0x1, 0x2, 0x3, 0x4, 0x5, 0x6],
604 );
605 write_elem(
606 &enc,
607 &mut writer,
608 0x0008,
609 0x010E,
610 VR::UR,
611 b"http://example.com",
612 );
613 write_elem(&enc, &mut writer, 0x0008, 0x0040, VR::US, &[0x87, 0x07]);
614 write_elem(&enc, &mut writer, 0x0018, 0x9917, VR::UT, b"No text ");
615 write_elem(
616 &enc,
617 &mut writer,
618 0x0008,
619 0x040C,
620 VR::UV,
621 &[0xAB, 0x54, 0xA9, 0x8C, 0xEB, 0x1F, 0x0A, 0xD2],
622 );
623
624 assert_eq!(&buf[..], &RAW[..]);
625 }
626
627 const RAW_SEQUENCE_ITEMS: &[u8] = &[
643 0x00, 0x08, 0x10, 0x3F, b'S', b'Q', 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0,
644 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0, 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE,
645 0xE0, 0xDD, 0x00, 0x00, 0x00, 0x00,
646 ];
647
648 #[test]
649 fn encode_items() -> Result {
650 let enc = ExplicitVRBigEndianEncoder::default();
651 let mut out = Vec::new();
652
653 {
654 let bytes_written = enc.encode_element_header(
655 &mut out,
656 DataElementHeader::new(Tag(0x0008, 0x103F), VR::SQ, Length::UNDEFINED),
657 )?;
658 assert_eq!(bytes_written, 12);
659 }
660 assert_eq!(out.len(), 12);
661
662 enc.encode_item_header(&mut out, Length::UNDEFINED.0)?;
663 assert_eq!(out.len(), 20);
664
665 enc.encode_item_delimiter(&mut out)?;
666 assert_eq!(out.len(), 28);
667
668 enc.encode_sequence_delimiter(&mut out)?;
669
670 assert_eq!(&out[..], RAW_SEQUENCE_ITEMS);
671
672 Ok(())
673 }
674}