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