docs: def _process_tags(self):
          """Validate standard tags and initialize attributes.
  
          Raise ValueError if tag values are not supported.
  
          """
          tags = self.tags
          for code, (name, default, dtype, count, validate) in TIFF_TAGS.items():
              if not (name in tags or default is None):
                  tags[name] = TIFFtag(code, dtype=dtype, count=count,
                                       value=default, name=name)
              if name in tags and validate:
                  try:
                      if tags[name].count == 1:
                          setattr(self, name, validate[tags[name].value])
                      else:
                          setattr(self, name, tuple(validate[value]
                                              for value in tags[name].value))
                  except KeyError:
                      raise ValueError("%s.value (%s) not supported" %
                                       (name, tags[name].value))
  
          tag = tags['bits_per_sample']
          if tag.count == 1:
              self.bits_per_sample = tag.value
          else:
              value = tag.value[:self.samples_per_pixel]
              if any((v-value[0] for v in value)):
                  self.bits_per_sample = value
              else:
                  self.bits_per_sample = value[0]
  
          tag = tags['sample_format']
          if tag.count == 1:
              self.sample_format = TIFF_SAMPLE_FORMATS[tag.value]
          else:
              value = tag.value[:self.samples_per_pixel]
              if any((v-value[0] for v in value)):
                  self.sample_format = [TIFF_SAMPLE_FORMATS[v] for v in value]
              else:
                  self.sample_format = TIFF_SAMPLE_FORMATS[value[0]]
  
          self.strips_per_image = int(math.floor(float(self.image_length +
                              self.rows_per_strip - 1) / self.rows_per_strip))
  
          key = (self.sample_format, self.bits_per_sample)
          self.dtype = self._dtype = TIFF_SAMPLE_DTYPES.get(key, None)
  
          if self.is_stk:
              planes = tags['mm_uic2'].count
              # consolidate mm_uci tags
              self.mm_uic_tags = Record(tags['mm_uic2'].value)
              for key in ('mm_uic3', 'mm_uic4', 'mm_uic1'):
                  if key in tags:
                      self.mm_uic_tags.update(tags[key].value)
              if self.planar_configuration == 'contig':
                  self._shape = (planes, 1, self.image_length,
                                 self.image_width, self.samples_per_pixel)
                  self.shape = tuple(self._shape[i] for i in (0, 2, 3, 4))
                  self.axes = "PYXS"
              else:
                  self._shape = (planes, self.samples_per_pixel,
                                 self.image_length, self.image_width, 1)
                  self.shape = self._shape[:4]
                  self.axes = "PSYX"
          elif self.is_palette:
              self.dtype = self.tags['color_map'].dtype[1]
              self.color_map = numpy.array(self.color_map, self.dtype)
              dmax = self.color_map.max()
              if dmax < 256:
                  self.dtype = numpy.uint8
                  self.color_map = self.color_map.astype(self.dtype)
              #else:
              #    self.dtype = numpy.uint8
              #    self.color_map >>= 8
              #    self.color_map = self.color_map.astype(self.dtype)
              self.color_map.shape = (3, -1)
              self._shape = (1, 1, self.image_length, self.image_width, 1)
              if self.color_map.shape[1] >= 2**self.bits_per_sample:
                  self.shape = (3, self.image_length, self.image_width)
                  self.axes = "SYX"
              else:
                  # LSM and FluoView
                  self.shape = (self.image_length, self.image_width)
                  self.axes = "YX"
          elif self.is_rgb or self.samples_per_pixel > 1:
              if self.planar_configuration == 'contig':
                  self._shape = (1, 1, self.image_length, self.image_width,
                                 self.samples_per_pixel)
                  self.shape = (self.image_length, self.image_width,
                                self.samples_per_pixel)
                  self.axes = "YXS"
              else:
                  self._shape = (1, self.samples_per_pixel, self.image_length,
                                 self.image_width, 1)
                  self.shape = self._shape[1:-1]
                  self.axes = "SYX"
              if self.is_rgb and 'extra_samples' in self.tags:
                  extra_samples = self.extra_samples
                  if self.tags['extra_samples'].count == 1:
                      extra_samples = (extra_samples, )
                  for exs in extra_samples:
                      if exs in ('unassalpha', 'assocalpha'):
                          if self.planar_configuration == 'contig':
                              self.shape = self.shape[:2] + (4,)
                          else:
                              self.shape = (4,) + self.shape[1:]
                          break
          else:
              self._shape = (1, 1, self.image_length, self.image_width, 1)
              self.shape = self._shape[2:4]
              self.axes = "YX"
  
          if not self.compression and not 'strip_byte_counts' in tags:
              self.strip_byte_counts = numpy.prod(self.shape) * (
                  self.bits_per_sample // 8)