def read(string, signature=true, options={})
      # (Re)Set variables:
      @str = string
      @overwrite = options[:overwrite]
      # Presence of the official DICOM signature:
      @signature = false
      # Default explicitness of start of DICOM string (if undefined it defaults to true):
      @explicit = options[:explicit].nil? ? true : options[:explicit]
      # Default endianness of start of DICOM string is little endian:
      @str_endian = false
      # A switch of endianness may occur after the initial meta group, an this needs to be monitored:
      @switched_endian = false
      # Explicitness of the remaining groups after the initial 0002 group:
      @rest_explicit = false
      # Endianness of the remaining groups after the first group:
      @rest_endian = false
      # When the string switch from group 0002 to a later group we will update encoding values, and this switch will keep track of that:
      @switched = options[:switched] ? options[:switched] : false
      # Keeping track of the data element parent status while parsing the DICOM string:
      @current_parent = self
      # Keeping track of what is the current data element:
      @current_element = self
      # Items contained under the pixel data element may contain data directly, so we need a variable to keep track of this:
      @enc_image = false
      # Assume header size is zero bytes until otherwise is determined:
      @header_length = 0
      # Assume string will be read successfully and toggle it later if we experience otherwise:
      @read_success = true
      # Our encoding instance:
      @stream = Stream.new(@str, @str_endian)
      # If a transfer syntax has been specified as an option for a DICOM object,
      # make sure that it makes it into the object:
      if options[:syntax]
        @transfer_syntax = options[:syntax]
        Element.new("0002,0010", options[:syntax], :parent => self) if self.is_a?(DObject)
      end
      # Check for header information if indicated:
      if signature
        # Read and verify the DICOM header:
        header = check_header
        # If the string is without the expected header, we will attempt
        # to read data elements from the very start of the string:
        if header == false
          @stream.skip(-132)
        elsif header.nil?
          # Not a valid DICOM string, return:
          @read_success = false
          return
        end
      end
      # Run a loop which parses Data Elements, one by one, until the end of the data string is reached:
      data_element = true
      while data_element do
        # Using a rescue clause since processing Data Elements can cause errors when parsing an invalid DICOM string.
        begin
          # Extracting Data element information (nil is returned if end of the string is encountered in a normal way).
          data_element = process_data_element
        rescue Exception => msg
          # The parse algorithm crashed. Set data_element as false to break
          # the loop and toggle the success boolean to indicate failure.
          @read_success = false
          data_element = false
          # Output the raised message as a warning:
          logger.warn(msg.to_s)
          # Ouput the backtrace as debug information:
          logger.debug(msg.backtrace)
          # Explain the failure as an error:
          logger.error("Parsing a Data Element has failed. This is likely caused by an invalid DICOM encoding.")
        end
      end
    end
def read(string, signature=true, options={})
      # (Re)Set variables:
      @str = string
      @overwrite = options[:overwrite]
      # Presence of the official DICOM signature:
      @signature = false
      # Default explicitness of start of DICOM string (if undefined it defaults to true):
      @explicit = options[:explicit].nil? ? true : options[:explicit]
      # Default endianness of start of DICOM string is little endian:
      @str_endian = false
      # A switch of endianness may occur after the initial meta group, an this needs to be monitored:
      @switched_endian = false
      # Explicitness of the remaining groups after the initial 0002 group:
      @rest_explicit = false
      # Endianness of the remaining groups after the first group:
      @rest_endian = false
      # When the string switch from group 0002 to a later group we will update encoding values, and this switch will keep track of that:
      @switched = options[:switched] ? options[:switched] : false
      # Keeping track of the data element parent status while parsing the DICOM string:
      @current_parent = self
      # Keeping track of what is the current data element:
      @current_element = self
      # Items contained under the pixel data element may contain data directly, so we need a variable to keep track of this:
      @enc_image = false
      # Assume header size is zero bytes until otherwise is determined:
      @header_length = 0
      # Assume string will be read successfully and toggle it later if we experience otherwise:
      @read_success = true
      # Our encoding instance:
      @stream = Stream.new(@str, @str_endian)
      # If a transfer syntax has been specified as an option for a DICOM object,
      # make sure that it makes it into the object:
      if options[:syntax]
        @transfer_syntax = options[:syntax]
        Element.new("0002,0010", options[:syntax], :parent => self) if self.is_a?(DObject)
      end
      # Check for header information if indicated:
      if signature
        # Read and verify the DICOM header:
        header = check_header
        # If the string is without the expected header, we will attempt
        # to read data elements from the very start of the string:
        if header == false
          @stream.skip(-132)
        elsif header.nil?
          # Not a valid DICOM string, return:
          @read_success = false
          return
        end
      end
      # Run a loop which parses Data Elements, one by one, until the end of the data string is reached:
      data_element = true
      while data_element do
        # Using a rescue clause since processing Data Elements can cause errors when parsing an invalid DICOM string.
        begin
          # Extracting Data element information (nil is returned if end of the string is encountered in a normal way).
          data_element = process_data_element
        rescue Exception => msg
          # The parse algorithm crashed. Set data_element as false to break
          # the loop and toggle the success boolean to indicate failure.
          @read_success = false
          data_element = false
          # Output the raised message as a warning:
          logger.warn(msg.to_s)
          # Ouput the backtrace as debug information:
          logger.debug(msg.backtrace)
          # Explain the failure as an error:
          logger.error("Parsing a Data Element has failed. This is likely caused by an invalid DICOM encoding.")
        end
      end
    end
Builds a DICOM object by parsing an encoded DICOM string.

 @param [String] string a binary DICOM string to be parsed
 @param [Boolean] signature if true (default), the parsing algorithm will look for the DICOM header signature
 @param [Hash] options the options to use for parsing the DICOM string
 @option options [Boolean] :overwrite for the rare case of a DICOM file containing duplicate elements, setting this as true instructs the parsing algorithm to overwrite the original element with duplicates
 @option options [String] :syntax if a syntax string is specified, the parsing algorithm is forced to use this transfer syntax when decoding the string