dicom 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +27 -27
- data/README.md +2 -1
- data/dicom.gemspec +8 -8
- data/lib/dicom/anonymizer.rb +3 -3
- data/lib/dicom/d_object.rb +2 -2
- data/lib/dicom/element.rb +278 -278
- data/lib/dicom/elemental.rb +121 -121
- data/lib/dicom/general/constants.rb +4 -1
- data/lib/dicom/general/version.rb +1 -1
- data/lib/dicom/image_item.rb +6 -6
- data/lib/dicom/item.rb +122 -122
- data/lib/dicom/link.rb +6 -6
- data/lib/dicom/sequence.rb +98 -98
- data/lib/dicom/stream.rb +461 -461
- metadata +23 -24
data/lib/dicom/elemental.rb
CHANGED
@@ -1,121 +1,121 @@
|
|
1
|
-
module DICOM
|
2
|
-
|
3
|
-
# The Elemental mix-in module contains methods that
|
4
|
-
# are common among the various element type classes:
|
5
|
-
# * Element
|
6
|
-
# * Item
|
7
|
-
# * Sequence
|
8
|
-
#
|
9
|
-
module Elemental
|
10
|
-
|
11
|
-
# The encoded, binary value of the elemental (String).
|
12
|
-
attr_reader :bin
|
13
|
-
# The elemental's length (
|
14
|
-
attr_reader :length
|
15
|
-
# The elemental's name (String).
|
16
|
-
attr_reader :name
|
17
|
-
# The parent of this elemental (which may be an Item, Sequence or DObject).
|
18
|
-
attr_reader :parent
|
19
|
-
# The elemental's tag (String).
|
20
|
-
attr_reader :tag
|
21
|
-
# The elemental's value representation (String).
|
22
|
-
attr_reader :vr
|
23
|
-
|
24
|
-
# Gives the method (symbol) corresponding to the name string of this element.
|
25
|
-
#
|
26
|
-
# @return [Symbol, NilClass] the matched element method (or nil, if no match is made)
|
27
|
-
#
|
28
|
-
def name_as_method
|
29
|
-
LIBRARY.as_method(@name)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Retrieves the entire chain of parents connected to this elemental
|
33
|
-
# (or an empty array, if the element is parent-less).
|
34
|
-
#
|
35
|
-
# @return [Array] array of parents (immediate parent first, top parent last)
|
36
|
-
#
|
37
|
-
def parents
|
38
|
-
all_parents = Array.new
|
39
|
-
# Extract all parents and add to array recursively:
|
40
|
-
if parent
|
41
|
-
all_parents = parent.parents if parent.parent
|
42
|
-
all_parents.insert(0, parent)
|
43
|
-
end
|
44
|
-
return all_parents
|
45
|
-
end
|
46
|
-
|
47
|
-
# Sets a specified parent instance as this elemental's parent, while taking
|
48
|
-
# care to delete this elemental from any previous parent, as well as adding
|
49
|
-
# itself to the new parent (unless new parent is nil).
|
50
|
-
#
|
51
|
-
# @param [DObject, Item, Sequence, NilClass] new_parent the new parent object for this elemental
|
52
|
-
# @example Create a new Sequence and connect it to a DObject instance
|
53
|
-
# structure_set_roi = Sequence.new("3006,0020")
|
54
|
-
# structure_set_roi.parent = dcm
|
55
|
-
#
|
56
|
-
def parent=(new_parent)
|
57
|
-
# First take care of 'dependencies':
|
58
|
-
if self.parent
|
59
|
-
# Remove ourselves from the previous parent:
|
60
|
-
if self.is_a?(Item)
|
61
|
-
self.parent.delete(self.index, :no_follow => true)
|
62
|
-
else
|
63
|
-
self.parent.delete(self.tag, :no_follow => true)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
if new_parent
|
67
|
-
# Add ourselves to the new parent:
|
68
|
-
if self.is_a?(Item)
|
69
|
-
new_parent.add_item(self, :no_follow => true)
|
70
|
-
else
|
71
|
-
new_parent.add(self, :no_follow => true)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
# Set the new parent (should we bother to test for parent validity here?):
|
75
|
-
@parent = new_parent
|
76
|
-
end
|
77
|
-
|
78
|
-
# Sets a specified parent instance as this elemental's parent, without doing any other updates,
|
79
|
-
# like removing the elemental from any previous parent or adding itself to the new parent.
|
80
|
-
#
|
81
|
-
# @param [DObject, Item, Sequence, NilClass] new_parent the new parent object for this elemental
|
82
|
-
#
|
83
|
-
def set_parent(new_parent)
|
84
|
-
# Set the new parent (should we bother to test for parent validity here?):
|
85
|
-
@parent = new_parent
|
86
|
-
end
|
87
|
-
|
88
|
-
# Returns a Stream instance which can be used for encoding a value to binary.
|
89
|
-
#
|
90
|
-
# @note Retrieves the Stream instance of the top parent DObject instance.
|
91
|
-
# If this fails, a new Stream instance is created (with little endian encoding assumed).
|
92
|
-
#
|
93
|
-
def stream
|
94
|
-
if top_parent.is_a?(DObject)
|
95
|
-
return top_parent.stream
|
96
|
-
else
|
97
|
-
return Stream.new(nil, file_endian=false)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns the top parent of a particular elemental.
|
102
|
-
#
|
103
|
-
# @note Unless the elemental, or one of its parent instances, are independent,
|
104
|
-
# the top parent will be a DObject instance.
|
105
|
-
#
|
106
|
-
def top_parent
|
107
|
-
# The top parent is determined recursively:
|
108
|
-
if parent
|
109
|
-
if parent.is_a?(DObject)
|
110
|
-
return parent
|
111
|
-
else
|
112
|
-
return parent.top_parent
|
113
|
-
end
|
114
|
-
else
|
115
|
-
return self
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
end
|
1
|
+
module DICOM
|
2
|
+
|
3
|
+
# The Elemental mix-in module contains methods that
|
4
|
+
# are common among the various element type classes:
|
5
|
+
# * Element
|
6
|
+
# * Item
|
7
|
+
# * Sequence
|
8
|
+
#
|
9
|
+
module Elemental
|
10
|
+
|
11
|
+
# The encoded, binary value of the elemental (String).
|
12
|
+
attr_reader :bin
|
13
|
+
# The elemental's length (Integer).
|
14
|
+
attr_reader :length
|
15
|
+
# The elemental's name (String).
|
16
|
+
attr_reader :name
|
17
|
+
# The parent of this elemental (which may be an Item, Sequence or DObject).
|
18
|
+
attr_reader :parent
|
19
|
+
# The elemental's tag (String).
|
20
|
+
attr_reader :tag
|
21
|
+
# The elemental's value representation (String).
|
22
|
+
attr_reader :vr
|
23
|
+
|
24
|
+
# Gives the method (symbol) corresponding to the name string of this element.
|
25
|
+
#
|
26
|
+
# @return [Symbol, NilClass] the matched element method (or nil, if no match is made)
|
27
|
+
#
|
28
|
+
def name_as_method
|
29
|
+
LIBRARY.as_method(@name)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Retrieves the entire chain of parents connected to this elemental
|
33
|
+
# (or an empty array, if the element is parent-less).
|
34
|
+
#
|
35
|
+
# @return [Array] array of parents (immediate parent first, top parent last)
|
36
|
+
#
|
37
|
+
def parents
|
38
|
+
all_parents = Array.new
|
39
|
+
# Extract all parents and add to array recursively:
|
40
|
+
if parent
|
41
|
+
all_parents = parent.parents if parent.parent
|
42
|
+
all_parents.insert(0, parent)
|
43
|
+
end
|
44
|
+
return all_parents
|
45
|
+
end
|
46
|
+
|
47
|
+
# Sets a specified parent instance as this elemental's parent, while taking
|
48
|
+
# care to delete this elemental from any previous parent, as well as adding
|
49
|
+
# itself to the new parent (unless new parent is nil).
|
50
|
+
#
|
51
|
+
# @param [DObject, Item, Sequence, NilClass] new_parent the new parent object for this elemental
|
52
|
+
# @example Create a new Sequence and connect it to a DObject instance
|
53
|
+
# structure_set_roi = Sequence.new("3006,0020")
|
54
|
+
# structure_set_roi.parent = dcm
|
55
|
+
#
|
56
|
+
def parent=(new_parent)
|
57
|
+
# First take care of 'dependencies':
|
58
|
+
if self.parent
|
59
|
+
# Remove ourselves from the previous parent:
|
60
|
+
if self.is_a?(Item)
|
61
|
+
self.parent.delete(self.index, :no_follow => true)
|
62
|
+
else
|
63
|
+
self.parent.delete(self.tag, :no_follow => true)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
if new_parent
|
67
|
+
# Add ourselves to the new parent:
|
68
|
+
if self.is_a?(Item)
|
69
|
+
new_parent.add_item(self, :no_follow => true)
|
70
|
+
else
|
71
|
+
new_parent.add(self, :no_follow => true)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# Set the new parent (should we bother to test for parent validity here?):
|
75
|
+
@parent = new_parent
|
76
|
+
end
|
77
|
+
|
78
|
+
# Sets a specified parent instance as this elemental's parent, without doing any other updates,
|
79
|
+
# like removing the elemental from any previous parent or adding itself to the new parent.
|
80
|
+
#
|
81
|
+
# @param [DObject, Item, Sequence, NilClass] new_parent the new parent object for this elemental
|
82
|
+
#
|
83
|
+
def set_parent(new_parent)
|
84
|
+
# Set the new parent (should we bother to test for parent validity here?):
|
85
|
+
@parent = new_parent
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns a Stream instance which can be used for encoding a value to binary.
|
89
|
+
#
|
90
|
+
# @note Retrieves the Stream instance of the top parent DObject instance.
|
91
|
+
# If this fails, a new Stream instance is created (with little endian encoding assumed).
|
92
|
+
#
|
93
|
+
def stream
|
94
|
+
if top_parent.is_a?(DObject)
|
95
|
+
return top_parent.stream
|
96
|
+
else
|
97
|
+
return Stream.new(nil, file_endian=false)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns the top parent of a particular elemental.
|
102
|
+
#
|
103
|
+
# @note Unless the elemental, or one of its parent instances, are independent,
|
104
|
+
# the top parent will be a DObject instance.
|
105
|
+
#
|
106
|
+
def top_parent
|
107
|
+
# The top parent is determined recursively:
|
108
|
+
if parent
|
109
|
+
if parent.is_a?(DObject)
|
110
|
+
return parent
|
111
|
+
else
|
112
|
+
return parent.top_parent
|
113
|
+
end
|
114
|
+
else
|
115
|
+
return self
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -168,7 +168,10 @@ module DICOM
|
|
168
168
|
'ISO_IR 126' => 'ISO-8859-7',
|
169
169
|
'ISO_IR 138' => 'ISO-8859-8',
|
170
170
|
'ISO_IR 148' => 'ISO-8859-9',
|
171
|
-
'ISO_IR 13' => '
|
171
|
+
'ISO_IR 13' => 'Shift_JIS',
|
172
|
+
'ISO 2022 IR 13' => 'Shift_JIS',
|
173
|
+
'ISO 2022 IR 13\\ISO 2022 IR 87' => 'Shift_JIS',
|
174
|
+
'ISO 2022 IR 87' => 'ISO-2022-JP',
|
172
175
|
'ISO_IR 166' => 'ISO-8859-11',
|
173
176
|
'GB18030' => 'GB18030',
|
174
177
|
'ISO_IR 192' => 'UTF-8'
|
data/lib/dicom/image_item.rb
CHANGED
@@ -349,13 +349,13 @@ module DICOM
|
|
349
349
|
raise "Missing Rows and/or Columns Element. Unable to construct pixel data array." unless num_rows and num_cols
|
350
350
|
if num_frames > 1 or options[:volume]
|
351
351
|
# Create an empty 3D NArray. fill it with pixels frame by frame, then reassign the pixels variable to it:
|
352
|
-
narr =
|
352
|
+
narr = Numo::Int16.zeros(num_frames, num_cols, num_rows)
|
353
353
|
num_frames.times do |i|
|
354
|
-
narr[i, true, true] = NArray
|
354
|
+
narr[i, true, true] = Numo::NArray[*pixels[(i * num_cols * num_rows)..((i + 1) * num_cols * num_rows - 1)]].reshape!(num_cols, num_rows)
|
355
355
|
end
|
356
356
|
pixels = narr
|
357
357
|
else
|
358
|
-
pixels = NArray
|
358
|
+
pixels = Numo::NArray[*pixels].reshape!(num_cols, num_rows)
|
359
359
|
end
|
360
360
|
# Remap the image from pixel values to presentation values if the user has requested this:
|
361
361
|
pixels = process_presentation_values_narray(pixels, -65535, 65535, options[:level]) if options[:remap] or options[:level]
|
@@ -680,7 +680,7 @@ module DICOM
|
|
680
680
|
end
|
681
681
|
# Need to convert to NArray?
|
682
682
|
if pixel_data.is_a?(Array)
|
683
|
-
n_arr = NArray
|
683
|
+
n_arr = Numo::NArray[*pixel_data]
|
684
684
|
else
|
685
685
|
n_arr = pixel_data
|
686
686
|
end
|
@@ -779,7 +779,7 @@ module DICOM
|
|
779
779
|
# Number of bytes used per pixel will determine how to unpack this:
|
780
780
|
case depth
|
781
781
|
when 8 # (1 byte)
|
782
|
-
template = 'BY' # Byte/Character/
|
782
|
+
template = 'BY' # Byte/Character/Integer
|
783
783
|
when 16 # (2 bytes)
|
784
784
|
if pixel_representation == 1
|
785
785
|
template = 'SS' # Signed short
|
@@ -834,4 +834,4 @@ module DICOM
|
|
834
834
|
end
|
835
835
|
|
836
836
|
end
|
837
|
-
end
|
837
|
+
end
|
data/lib/dicom/item.rb
CHANGED
@@ -1,122 +1,122 @@
|
|
1
|
-
module DICOM
|
2
|
-
|
3
|
-
# The Item class handles information related to items - the elements contained in sequences.
|
4
|
-
#
|
5
|
-
# === Inheritance
|
6
|
-
#
|
7
|
-
# As the Item class inherits from the ImageItem class, which itself inherits from the Parent class,
|
8
|
-
# all ImageItem and Parent methods are also available to instances of Item.
|
9
|
-
#
|
10
|
-
class Item < ImageItem
|
11
|
-
|
12
|
-
include Elemental
|
13
|
-
include ElementalParent
|
14
|
-
|
15
|
-
# The index of this Item in the group of items belonging to its parent. If the Item is without parent, index is nil.
|
16
|
-
attr_accessor :index
|
17
|
-
|
18
|
-
# Creates an Item instance.
|
19
|
-
#
|
20
|
-
# Normally, an Item contains data elements and/or sequences. However,
|
21
|
-
# in some cases, an Item will instead/also carry binary string data,
|
22
|
-
# like the pixel data of an encapsulated image fragment.
|
23
|
-
#
|
24
|
-
# @param [Hash] options the options to use for creating the item
|
25
|
-
# @option options [String] :bin a binary string to be carried by the item
|
26
|
-
# @option options [String] :indexif the item is to be inserted at a specific index (Item number), this option parameter needs to set
|
27
|
-
# @option options [String] :length theiItem length (which either refers to the length of the encoded string of children of this item, or the length of its binary data)
|
28
|
-
# @option options [String] :name the name of the item may be specified upon creation (if not, a default name is used)
|
29
|
-
# @option options [String] :parent a Sequence or DObject instance which the item instance shall belong to
|
30
|
-
# @option options [String] :vr the value representation of the item may be specified upon creation (if not, a default vr is used)
|
31
|
-
#
|
32
|
-
# @example Create an empty Item and connect it to the "Structure Set ROI Sequence"
|
33
|
-
# item = Item.new(:parent => dcm["3006,0020"])
|
34
|
-
# @example Create a "Pixel Data Item" which carries an encapsulated image frame (a pre-encoded binary)
|
35
|
-
# pixel_item = Item.new(:bin => processed_pixel_data, :parent => dcm["7FE0,0010"][1])
|
36
|
-
#
|
37
|
-
def initialize(options={})
|
38
|
-
# Set common parent variables:
|
39
|
-
initialize_parent
|
40
|
-
# Set instance variables:
|
41
|
-
@tag = ITEM_TAG
|
42
|
-
@value = nil
|
43
|
-
@name = options[:name] || "Item"
|
44
|
-
@vr = options[:vr] || ITEM_VR
|
45
|
-
if options[:bin]
|
46
|
-
self.bin = options[:bin]
|
47
|
-
else
|
48
|
-
@length = options[:length] || -1
|
49
|
-
end
|
50
|
-
if options[:parent]
|
51
|
-
@parent = options[:parent]
|
52
|
-
@index = options[:index] if options[:index]
|
53
|
-
@parent.add_item(self, :index => options[:index], :no_follow => true)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# Checks for equality.
|
58
|
-
#
|
59
|
-
# Other and self are considered equivalent if they are
|
60
|
-
# of compatible types and their attributes are equivalent.
|
61
|
-
#
|
62
|
-
# @param other an object to be compared with self.
|
63
|
-
# @return [Boolean] true if self and other are considered equivalent
|
64
|
-
#
|
65
|
-
def ==(other)
|
66
|
-
if other.respond_to?(:to_item)
|
67
|
-
other.send(:state) == state
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
alias_method :eql?, :==
|
72
|
-
|
73
|
-
# Sets the binary string that the Item will contain.
|
74
|
-
#
|
75
|
-
# @param [String] new_bin a binary string of encoded data
|
76
|
-
# @example Insert a custom jpeg in the (encapsulated) pixel data element (in it's first pixel data item)
|
77
|
-
# dcm['7FE0,0010'][1].children.first.bin = jpeg_binary_string
|
78
|
-
#
|
79
|
-
def bin=(new_bin)
|
80
|
-
raise ArgumentError, "Invalid parameter type. String was expected, got #{new_bin.class}." unless new_bin.is_a?(String)
|
81
|
-
# Add an empty byte at the end if the length of the binary is odd:
|
82
|
-
if new_bin.length.odd?
|
83
|
-
@bin = new_bin + "\x00"
|
84
|
-
else
|
85
|
-
@bin = new_bin
|
86
|
-
end
|
87
|
-
@value = nil
|
88
|
-
@length = @bin.length
|
89
|
-
end
|
90
|
-
|
91
|
-
# Computes a hash code for this object.
|
92
|
-
#
|
93
|
-
# @note Two objects with the same attributes will have the same hash code.
|
94
|
-
#
|
95
|
-
# @return [
|
96
|
-
#
|
97
|
-
def hash
|
98
|
-
state.hash
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns self.
|
102
|
-
#
|
103
|
-
# @return [Item] self
|
104
|
-
#
|
105
|
-
def to_item
|
106
|
-
self
|
107
|
-
end
|
108
|
-
|
109
|
-
|
110
|
-
private
|
111
|
-
|
112
|
-
|
113
|
-
# Collects the attributes of this instance.
|
114
|
-
#
|
115
|
-
# @return [Array<String, Sequence, Element>] an array of attributes
|
116
|
-
#
|
117
|
-
def state
|
118
|
-
[@vr, @name, @tags]
|
119
|
-
end
|
120
|
-
|
121
|
-
end
|
122
|
-
end
|
1
|
+
module DICOM
|
2
|
+
|
3
|
+
# The Item class handles information related to items - the elements contained in sequences.
|
4
|
+
#
|
5
|
+
# === Inheritance
|
6
|
+
#
|
7
|
+
# As the Item class inherits from the ImageItem class, which itself inherits from the Parent class,
|
8
|
+
# all ImageItem and Parent methods are also available to instances of Item.
|
9
|
+
#
|
10
|
+
class Item < ImageItem
|
11
|
+
|
12
|
+
include Elemental
|
13
|
+
include ElementalParent
|
14
|
+
|
15
|
+
# The index of this Item in the group of items belonging to its parent. If the Item is without parent, index is nil.
|
16
|
+
attr_accessor :index
|
17
|
+
|
18
|
+
# Creates an Item instance.
|
19
|
+
#
|
20
|
+
# Normally, an Item contains data elements and/or sequences. However,
|
21
|
+
# in some cases, an Item will instead/also carry binary string data,
|
22
|
+
# like the pixel data of an encapsulated image fragment.
|
23
|
+
#
|
24
|
+
# @param [Hash] options the options to use for creating the item
|
25
|
+
# @option options [String] :bin a binary string to be carried by the item
|
26
|
+
# @option options [String] :indexif the item is to be inserted at a specific index (Item number), this option parameter needs to set
|
27
|
+
# @option options [String] :length theiItem length (which either refers to the length of the encoded string of children of this item, or the length of its binary data)
|
28
|
+
# @option options [String] :name the name of the item may be specified upon creation (if not, a default name is used)
|
29
|
+
# @option options [String] :parent a Sequence or DObject instance which the item instance shall belong to
|
30
|
+
# @option options [String] :vr the value representation of the item may be specified upon creation (if not, a default vr is used)
|
31
|
+
#
|
32
|
+
# @example Create an empty Item and connect it to the "Structure Set ROI Sequence"
|
33
|
+
# item = Item.new(:parent => dcm["3006,0020"])
|
34
|
+
# @example Create a "Pixel Data Item" which carries an encapsulated image frame (a pre-encoded binary)
|
35
|
+
# pixel_item = Item.new(:bin => processed_pixel_data, :parent => dcm["7FE0,0010"][1])
|
36
|
+
#
|
37
|
+
def initialize(options={})
|
38
|
+
# Set common parent variables:
|
39
|
+
initialize_parent
|
40
|
+
# Set instance variables:
|
41
|
+
@tag = ITEM_TAG
|
42
|
+
@value = nil
|
43
|
+
@name = options[:name] || "Item"
|
44
|
+
@vr = options[:vr] || ITEM_VR
|
45
|
+
if options[:bin]
|
46
|
+
self.bin = options[:bin]
|
47
|
+
else
|
48
|
+
@length = options[:length] || -1
|
49
|
+
end
|
50
|
+
if options[:parent]
|
51
|
+
@parent = options[:parent]
|
52
|
+
@index = options[:index] if options[:index]
|
53
|
+
@parent.add_item(self, :index => options[:index], :no_follow => true)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Checks for equality.
|
58
|
+
#
|
59
|
+
# Other and self are considered equivalent if they are
|
60
|
+
# of compatible types and their attributes are equivalent.
|
61
|
+
#
|
62
|
+
# @param other an object to be compared with self.
|
63
|
+
# @return [Boolean] true if self and other are considered equivalent
|
64
|
+
#
|
65
|
+
def ==(other)
|
66
|
+
if other.respond_to?(:to_item)
|
67
|
+
other.send(:state) == state
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
alias_method :eql?, :==
|
72
|
+
|
73
|
+
# Sets the binary string that the Item will contain.
|
74
|
+
#
|
75
|
+
# @param [String] new_bin a binary string of encoded data
|
76
|
+
# @example Insert a custom jpeg in the (encapsulated) pixel data element (in it's first pixel data item)
|
77
|
+
# dcm['7FE0,0010'][1].children.first.bin = jpeg_binary_string
|
78
|
+
#
|
79
|
+
def bin=(new_bin)
|
80
|
+
raise ArgumentError, "Invalid parameter type. String was expected, got #{new_bin.class}." unless new_bin.is_a?(String)
|
81
|
+
# Add an empty byte at the end if the length of the binary is odd:
|
82
|
+
if new_bin.length.odd?
|
83
|
+
@bin = new_bin + "\x00"
|
84
|
+
else
|
85
|
+
@bin = new_bin
|
86
|
+
end
|
87
|
+
@value = nil
|
88
|
+
@length = @bin.length
|
89
|
+
end
|
90
|
+
|
91
|
+
# Computes a hash code for this object.
|
92
|
+
#
|
93
|
+
# @note Two objects with the same attributes will have the same hash code.
|
94
|
+
#
|
95
|
+
# @return [Integer] the object's hash code
|
96
|
+
#
|
97
|
+
def hash
|
98
|
+
state.hash
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns self.
|
102
|
+
#
|
103
|
+
# @return [Item] self
|
104
|
+
#
|
105
|
+
def to_item
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
|
113
|
+
# Collects the attributes of this instance.
|
114
|
+
#
|
115
|
+
# @return [Array<String, Sequence, Element>] an array of attributes
|
116
|
+
#
|
117
|
+
def state
|
118
|
+
[@vr, @name, @tags]
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|