Skip to content

Commit

Permalink
Minor updates to elements
Browse files Browse the repository at this point in the history
  • Loading branch information
karl-exini committed Jun 23, 2019
1 parent eb1a7ea commit 92ba92c
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ project/plugins/project/
.scala_dependencies
.worksheet
.idea
.vscode


23 changes: 17 additions & 6 deletions src/main/scala/com/exini/dicom/data/Elements.scala
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,9 @@ case class Elements(characterSets: CharacterSets, zoneOffset: ZoneOffset, data:
def sorted(): Elements = copy(data = data.sortBy(_.tag))

def toList: List[ElementSet] = data.toList
def toElements: List[Element] = toList.flatMap(_.toElements)
def toParts: List[DicomPart] = toElements.flatMap(_.toParts)
def toElements(withPreamble: Boolean = true): List[Element] =
if (withPreamble) PreambleElement :: toList.flatMap(_.toElements) else toList.flatMap(_.toElements)
def toParts(withPreamble: Boolean = true): List[DicomPart] = toElements(withPreamble).flatMap(_.toParts)
def toBytes(withPreamble: Boolean = true): ByteString =
data.map(_.toBytes).foldLeft(if (withPreamble) PreambleElement.toBytes else ByteString.empty)(_ ++ _)

Expand Down Expand Up @@ -541,7 +542,10 @@ object Elements {
def setValue(value: Value): ValueElement = copy(value = value.ensurePadding(vr))
override def toBytes: ByteString = toParts.map(_.bytes).reduce(_ ++ _)
override def toParts: List[DicomPart] =
HeaderPart(tag, vr, length, isFileMetaInformation(tag), bigEndian, explicitVR) :: ValueChunk(bigEndian, value.bytes, last = true) :: Nil
if (length > 0)
HeaderPart(tag, vr, length, isFileMetaInformation(tag), bigEndian, explicitVR) :: ValueChunk(bigEndian, value.bytes, last = true) :: Nil
else
HeaderPart(tag, vr, length, isFileMetaInformation(tag), bigEndian, explicitVR) :: Nil
override def toElements: List[Element] = this :: Nil
override def toString: String = {
val strings = value.toStrings(vr, bigEndian, defaultCharacterSet)
Expand All @@ -563,20 +567,26 @@ object Elements {
}

case class SequenceElement(tag: Int, length: Long, bigEndian: Boolean = false, explicitVR: Boolean = true) extends Element {
def indeterminate: Boolean = length == indeterminateLength
override def toBytes: ByteString = HeaderPart(tag, VR.SQ, length, isFmi = false, bigEndian, explicitVR).bytes
override def toParts: List[DicomPart] = SequencePart(tag, length, bigEndian, explicitVR, toBytes) :: Nil
override def toString: String = s"SequenceElement(${tagToString(tag)} SQ # $length ${Lookup.keywordOf(tag)})"
}

case class FragmentsElement(tag: Int, vr: VR, bigEndian: Boolean = false, explicitVR: Boolean = true) extends Element {
override def toBytes: ByteString = toParts.head.bytes
override def toParts: List[DicomPart] = HeaderPart(tag, vr, indeterminateLength, isFmi = false, bigEndian, explicitVR) :: Nil
override def toParts: List[DicomPart] = FragmentsPart(tag, indeterminateLength, vr, bigEndian, explicitVR,
HeaderPart(this.tag, this.vr, indeterminateLength, isFmi = false, this.bigEndian, this.explicitVR).bytes) :: Nil
override def toString: String = s"FragmentsElement(${tagToString(tag)} $vr # ${Lookup.keywordOf(tag)})"
}

case class FragmentElement(index: Int, length: Long, value: Value, bigEndian: Boolean = false) extends Element {
override def toBytes: ByteString = toParts.map(_.bytes).reduce(_ ++ _)
override def toParts: List[DicomPart] = ItemElement(index, value.length, bigEndian).toParts ::: ValueChunk(bigEndian, value.bytes, last = true) :: Nil
override def toParts: List[DicomPart] =
if (value.length > 0)
ItemElement(index, value.length, bigEndian).toParts ::: ValueChunk(bigEndian, value.bytes, last = true) :: Nil
else
ItemElement(index, value.length, bigEndian).toParts ::: Nil
override def toString: String = s"FragmentElement(index = $index, length = $length)"
}

Expand All @@ -585,6 +595,7 @@ object Elements {
}

case class ItemElement(index: Int, length: Long, bigEndian: Boolean = false) extends Element {
def indeterminate: Boolean = length == indeterminateLength
override def toBytes: ByteString = tagToBytes(Tag.Item, bigEndian) ++ intToBytes(length.toInt, bigEndian)
override def toParts: List[DicomPart] = ItemPart(index, length, bigEndian, toBytes) :: Nil
override def toString: String = s"ItemElement(index = $index, length = $length)"
Expand Down Expand Up @@ -640,7 +651,7 @@ object Elements {

case class Item(elements: Elements, length: Long = indeterminateLength, bigEndian: Boolean = false) {
val indeterminate: Boolean = length == indeterminateLength
def toElements(index: Int): List[Element] = ItemElement(index, length, bigEndian) :: elements.toElements :::
def toElements(index: Int): List[Element] = ItemElement(index, length, bigEndian) :: elements.toElements(false) :::
ItemDelimitationElement(index, marker = !indeterminate, bigEndian) :: Nil
def toBytes: ByteString = toElements(1).map(_.toBytes).reduce(_ ++ _)
def setElements(elements: Elements): Item = {
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/exini/dicom/streams/DicomFlows.scala
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ object DicomFlows {
val length = fmiElementsNoLength.data.map(_.toBytes.length).sum
val lengthHeader = HeaderPart(Tag.FileMetaInformationGroupLength, VR.UL, 4, isFmi = true, bigEndian, explicitVR)
val lengthChunk = ValueChunk(bigEndian, intToBytes(length, bigEndian), last = true)
fmi = lengthHeader :: lengthChunk :: fmiElementsNoLength.toParts
fmi = lengthHeader :: lengthChunk :: fmiElementsNoLength.toParts(false)
}
Nil

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/com/exini/dicom/data/ElementsTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ class ElementsTest extends FlatSpec with Matchers {

it should "provide a legible toString" in {
val updated = elements.set(Fragments(Tag.PixelData, VR.OB, None, List(Fragment(4, Value(ByteString(1, 2, 3, 4))))))
updated.toString.count(_ == System.lineSeparator.charAt(0)) shouldBe updated.toElements.length - 1
updated.toString.count(_ == System.lineSeparator.charAt(0)) shouldBe updated.toElements(false).length - 1
}

it should "create file meta information" in {
Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/com/exini/dicom/streams/ElementSinkTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ElementSinkTest extends TestKit(ActorSystem("ElementSinkSpec")) with FlatS

val elements = Await.result(Source(elementList).runWith(elementSink), 5.seconds)

elements.toElements shouldBe elementList
elements.toElements(false) shouldBe elementList
}

it should "handle zero length values, fragments, sequences and items" in {
Expand All @@ -69,7 +69,7 @@ class ElementSinkTest extends TestKit(ActorSystem("ElementSinkSpec")) with FlatS

val elements = Await.result(Source(elementList).runWith(elementSink), 5.seconds)

elements.toElements shouldBe elementList
elements.toElements(false) shouldBe elementList
}

it should "convert an empty offsets table item to an empty list of offsets" in {
Expand Down

0 comments on commit 92ba92c

Please sign in to comment.