예제 #1
0
    def parse_array_definition(self):
        """Reads and returns the element type and length of the array.

        The position in the file must be just after the
        array encoded dtype.

        """
        self.skipif4()
        enc_eltype = iou.read_long(self.f, "big")
        self.skipif4()
        length = iou.read_long(self.f, "big")
        return length, enc_eltype
예제 #2
0
    def parse_array_definition(self):
        """Reads and returns the element type and length of the array.

        The position in the file must be just after the
        array encoded dtype.

        """
        self.skipif4()
        enc_eltype = iou.read_long(self.f, "big")
        self.skipif4()
        length = iou.read_long(self.f, "big")
        return length, enc_eltype
예제 #3
0
    def parse_struct_definition(self):
        """Reads and returns the struct definition tuple.

        The position in the file must be just after the
        struct encoded dtype.

        """
        self.f.seek(4, 1)  # Skip the name length
        self.skipif4(2)
        nfields = iou.read_long(self.f, "big")
        definition = ()
        for ifield in range(nfields):
            self.f.seek(4, 1)
            self.skipif4(2)
            definition += (iou.read_long(self.f, "big"),)

        return definition
예제 #4
0
    def parse_string_definition(self):
        """Reads and returns the length of the string.

        The position in the file must be just after the
        string encoded dtype.
        """
        self.skipif4()
        return iou.read_long(self.f, "big")
예제 #5
0
    def parse_header(self):
        self.dm_version = iou.read_long(self.f, "big")
        if self.dm_version not in (3, 4):
            raise NotImplementedError(
                "Currently we only support reading DM versions 3 and 4 but "
                "this file "
                "seems to be version %s " % self.dm_version)
        filesizeB = self.read_l_or_q(self.f, "big")
        is_little_endian = iou.read_long(self.f, "big")

        _logger.info('DM version: %i', self.dm_version)
        _logger.info('size %i B', filesizeB)
        _logger.info('Is file Little endian? %s', bool(is_little_endian))
        if bool(is_little_endian):
            self.endian = 'little'
        else:
            self.endian = 'big'
예제 #6
0
    def parse_struct_definition(self):
        """Reads and returns the struct definition tuple.

        The position in the file must be just after the
        struct encoded dtype.

        """
        self.f.seek(4, 1)  # Skip the name length
        self.skipif4(2)
        nfields = iou.read_long(self.f, "big")
        definition = ()
        for ifield in range(nfields):
            self.f.seek(4, 1)
            self.skipif4(2)
            definition += (iou.read_long(self.f, "big"), )

        return definition
예제 #7
0
    def parse_string_definition(self):
        """Reads and returns the length of the string.

        The position in the file must be just after the
        string encoded dtype.
        """
        self.skipif4()
        return iou.read_long(self.f, "big")
예제 #8
0
    def parse_header(self):
        self.dm_version = iou.read_long(self.f, "big")
        if self.dm_version not in (3, 4):
            raise NotImplementedError(
                "Currently we only support reading DM versions 3 and 4 but "
                "this file "
                "seems to be version %s " % self.dm_version)
        filesizeB = self.read_l_or_q(self.f, "big")
        is_little_endian = iou.read_long(self.f, "big")

        _logger.info('DM version: %i', self.dm_version)
        _logger.info('size %i B', filesizeB)
        _logger.info('Is file Little endian? %s', bool(is_little_endian))
        if bool(is_little_endian):
            self.endian = 'little'
        else:
            self.endian = 'big'
예제 #9
0
 def parse_tag_group(self, skip4=1):
     """Parse the root TagGroup of the given DM3 file f.
     Returns the tuple (is_sorted, is_open, n_tags).
     endian can be either 'big' or 'little'.
     """
     is_sorted = iou.read_byte(self.f, "big")
     is_open = iou.read_byte(self.f, "big")
     self.skipif4(n=skip4)
     n_tags = iou.read_long(self.f, "big")
     return bool(is_sorted), bool(is_open), n_tags
예제 #10
0
 def parse_tag_group(self, skip4=1):
     """Parse the root TagGroup of the given DM3 file f.
     Returns the tuple (is_sorted, is_open, n_tags).
     endian can be either 'big' or 'little'.
     """
     is_sorted = iou.read_byte(self.f, "big")
     is_open = iou.read_byte(self.f, "big")
     self.skipif4(n=skip4)
     n_tags = iou.read_long(self.f, "big")
     return bool(is_sorted), bool(is_open), n_tags
예제 #11
0
    def parse_tags(self, ntags, group_name='root', group_dict={}):
        """Parse the DM file into a dictionary.

        """
        unnammed_data_tags = 0
        unnammed_group_tags = 0
        for tag in range(ntags):
            _logger.debug('Reading tag name at address: %s', self.f.tell())
            tag_header = self.parse_tag_header()
            tag_name = tag_header['tag_name']

            skip = True if (group_name == "ImageData" and
                            tag_name == "Data") else False
            _logger.debug('Tag name: %s', tag_name[:20])
            _logger.debug('Tag ID: %s', tag_header['tag_id'])

            if tag_header['tag_id'] == 21:  # it's a TagType (DATA)
                if not tag_name:
                    tag_name = 'Data%i' % unnammed_data_tags
                    unnammed_data_tags += 1

                _logger.debug('Reading data tag at address: %s', self.f.tell())

                # Start reading the data
                # Raises IOError if it is wrong
                self.check_data_tag_delimiter()
                self.skipif4()
                infoarray_size = iou.read_long(self.f, 'big')
                _logger.debug("Infoarray size: %s", infoarray_size)
                self.skipif4()
                if infoarray_size == 1:  # Simple type
                    _logger.debug("Reading simple data")
                    etype = iou.read_long(self.f, "big")
                    data = self.read_simple_data(etype)
                elif infoarray_size == 2:  # String
                    _logger.debug("Reading string")
                    enctype = iou.read_long(self.f, "big")
                    if enctype != 18:
                        raise IOError("Expected 18 (string), got %i" % enctype)
                    string_length = self.parse_string_definition()
                    data = self.read_string(string_length, skip=skip)
                elif infoarray_size == 3:  # Array of simple type
                    _logger.debug("Reading simple array")
                    # Read array header
                    enctype = iou.read_long(self.f, "big")
                    if enctype != 20:  # Should be 20 if it is an array
                        raise IOError("Expected 20 (string), got %i" % enctype)
                    size, enc_eltype = self.parse_array_definition()
                    data = self.read_array(size, enc_eltype, skip=skip)
                elif infoarray_size > 3:
                    enctype = iou.read_long(self.f, "big")
                    if enctype == 15:  # It is a struct
                        _logger.debug("Reading struct")
                        definition = self.parse_struct_definition()
                        _logger.debug("Struct definition %s", definition)
                        data = self.read_struct(definition, skip=skip)
                    elif enctype == 20:  # It is an array of complex type
                        # Read complex array info
                        # The structure is
                        # 20 <4>, ?  <4>, enc_dtype <4>, definition <?>,
                        # size <4>
                        self.skipif4()
                        enc_eltype = iou.read_long(self.f, "big")
                        if enc_eltype == 15:  # Array of structs
                            _logger.debug("Reading array of structs")
                            definition = self.parse_struct_definition()
                            self.skipif4()  # Padding?
                            size = iou.read_long(self.f, "big")
                            _logger.debug("Struct definition: %s", definition)
                            _logger.debug("Array size: %s", size)
                            data = self.read_array(
                                size=size,
                                enc_eltype=enc_eltype,
                                extra={"definition": definition},
                                skip=skip)
                        elif enc_eltype == 18:  # Array of strings
                            _logger.debug("Reading array of strings")
                            string_length = \
                                self.parse_string_definition()
                            size = iou.read_long(self.f, "big")
                            data = self.read_array(
                                size=size,
                                enc_eltype=enc_eltype,
                                extra={"length": string_length},
                                skip=skip)
                        elif enc_eltype == 20:  # Array of arrays
                            _logger.debug("Reading array of arrays")
                            el_length, enc_eltype = \
                                self.parse_array_definition()
                            size = iou.read_long(self.f, "big")
                            data = self.read_array(
                                size=size,
                                enc_eltype=enc_eltype,
                                extra={"size": el_length},
                                skip=skip)

                else:  # Infoarray_size < 1
                    raise IOError("Invalided infoarray size ", infoarray_size)

                group_dict[tag_name] = data

            elif tag_header['tag_id'] == 20:  # it's a TagGroup (GROUP)
                if not tag_name:
                    tag_name = 'TagGroup%i' % unnammed_group_tags
                    unnammed_group_tags += 1
                _logger.debug(
                    'Reading Tag group at address: %s',
                    self.f.tell())
                ntags = self.parse_tag_group(skip4=3)[2]
                group_dict[tag_name] = {}
                self.parse_tags(
                    ntags=ntags,
                    group_name=tag_name,
                    group_dict=group_dict[tag_name])
            else:
                _logger.debug('File address:', self.f.tell())
                raise DM3TagIDError(tag_header['tag_id'])
예제 #12
0
    def parse_tags(self, ntags, group_name='root', group_dict={}):
        """Parse the DM file into a dictionary.

        """
        unnammed_data_tags = 0
        unnammed_group_tags = 0
        for tag in range(ntags):
            _logger.debug('Reading tag name at address: %s', self.f.tell())
            tag_header = self.parse_tag_header()
            tag_name = tag_header['tag_name']

            skip = True if (group_name == "ImageData"
                            and tag_name == "Data") else False
            _logger.debug('Tag name: %s', tag_name[:20])
            _logger.debug('Tag ID: %s', tag_header['tag_id'])

            if tag_header['tag_id'] == 21:  # it's a TagType (DATA)
                if not tag_name:
                    tag_name = 'Data%i' % unnammed_data_tags
                    unnammed_data_tags += 1

                _logger.debug('Reading data tag at address: %s', self.f.tell())

                # Start reading the data
                # Raises IOError if it is wrong
                self.check_data_tag_delimiter()
                self.skipif4()
                infoarray_size = iou.read_long(self.f, 'big')
                _logger.debug("Infoarray size: %s", infoarray_size)
                self.skipif4()
                if infoarray_size == 1:  # Simple type
                    _logger.debug("Reading simple data")
                    etype = iou.read_long(self.f, "big")
                    data = self.read_simple_data(etype)
                elif infoarray_size == 2:  # String
                    _logger.debug("Reading string")
                    enctype = iou.read_long(self.f, "big")
                    if enctype != 18:
                        raise IOError("Expected 18 (string), got %i" % enctype)
                    string_length = self.parse_string_definition()
                    data = self.read_string(string_length, skip=skip)
                elif infoarray_size == 3:  # Array of simple type
                    _logger.debug("Reading simple array")
                    # Read array header
                    enctype = iou.read_long(self.f, "big")
                    if enctype != 20:  # Should be 20 if it is an array
                        raise IOError("Expected 20 (string), got %i" % enctype)
                    size, enc_eltype = self.parse_array_definition()
                    data = self.read_array(size, enc_eltype, skip=skip)
                elif infoarray_size > 3:
                    enctype = iou.read_long(self.f, "big")
                    if enctype == 15:  # It is a struct
                        _logger.debug("Reading struct")
                        definition = self.parse_struct_definition()
                        _logger.debug("Struct definition %s", definition)
                        data = self.read_struct(definition, skip=skip)
                    elif enctype == 20:  # It is an array of complex type
                        # Read complex array info
                        # The structure is
                        # 20 <4>, ?  <4>, enc_dtype <4>, definition <?>,
                        # size <4>
                        self.skipif4()
                        enc_eltype = iou.read_long(self.f, "big")
                        if enc_eltype == 15:  # Array of structs
                            _logger.debug("Reading array of structs")
                            definition = self.parse_struct_definition()
                            self.skipif4()  # Padding?
                            size = iou.read_long(self.f, "big")
                            _logger.debug("Struct definition: %s", definition)
                            _logger.debug("Array size: %s", size)
                            data = self.read_array(
                                size=size,
                                enc_eltype=enc_eltype,
                                extra={"definition": definition},
                                skip=skip)
                        elif enc_eltype == 18:  # Array of strings
                            _logger.debug("Reading array of strings")
                            string_length = \
                                self.parse_string_definition()
                            size = iou.read_long(self.f, "big")
                            data = self.read_array(
                                size=size,
                                enc_eltype=enc_eltype,
                                extra={"length": string_length},
                                skip=skip)
                        elif enc_eltype == 20:  # Array of arrays
                            _logger.debug("Reading array of arrays")
                            el_length, enc_eltype = \
                                self.parse_array_definition()
                            size = iou.read_long(self.f, "big")
                            data = self.read_array(size=size,
                                                   enc_eltype=enc_eltype,
                                                   extra={"size": el_length},
                                                   skip=skip)

                else:  # Infoarray_size < 1
                    raise IOError("Invalided infoarray size ", infoarray_size)

                group_dict[tag_name] = data

            elif tag_header['tag_id'] == 20:  # it's a TagGroup (GROUP)
                if not tag_name:
                    tag_name = 'TagGroup%i' % unnammed_group_tags
                    unnammed_group_tags += 1
                _logger.debug('Reading Tag group at address: %s',
                              self.f.tell())
                ntags = self.parse_tag_group(skip4=3)[2]
                group_dict[tag_name] = {}
                self.parse_tags(ntags=ntags,
                                group_name=tag_name,
                                group_dict=group_dict[tag_name])
            else:
                _logger.debug('File address:', self.f.tell())
                raise DM3TagIDError(tag_header['tag_id'])