def _gettags(self, codes=None, lock=None):
        """Return list of (code, TiffTag) from file."""
        fh = self.parent.filehandle
        tiff = self.parent.tiff
        unpack = struct.unpack
        lock = NullContext() if lock is None else lock
        tags = []

        with lock:
            fh.seek(self.offset)
            try:
                tagno = unpack(tiff.tagnoformat, fh.read(tiff.tagnosize))[0]
                if tagno > 4096:
                    raise TiffFileError('suspicious number of tags')
            except Exception:
                raise TiffFileError(
                    'corrupted page list at offset %i' % self.offset)

            tagoffset = self.offset + tiff.tagnosize  # fh.tell()
            tagsize = tiff.tagsize
            tagindex = -tagsize
            codeformat = tiff.tagformat1[:2]
            tagbytes = fh.read(tagsize * tagno)

            for _ in range(tagno):
                tagindex += tagsize
                code = unpack(codeformat, tagbytes[tagindex:tagindex+2])[0]
                if codes and code not in codes:
                    continue
                try:
                    tag = TiffTag(self.parent,
                                  tagbytes[tagindex:tagindex+tagsize],
                                  tagoffset+tagindex)
                except TiffFileError as exc:
                    log.warning('%s: %s', exc.__class__.__name__, exc)
                    continue
                tags.append((code, tag))

        return tags