async def updateImageMetadata(self):
    """ Partially download image file(s) to get its real metadata, or get it from cache. """
    assert(self.needMetadataUpdate())

    width_sum, height_sum = 0, 0

    # only download metadata for the needed images to get full size
    idxs = []
    assert(is_square(len(self.urls)))
    sq = int(math.sqrt(len(self.urls)))
    for x in range(sq):
      for y in range(sq):
        if x == y:
          idxs.append((x * sq + y, x, y))

    for idx, x, y in idxs:
      url = self.urls[idx]
      format, width, height = None, None, None

      try:
        format, width, height = pickle.loads(__class__.metadata_cache[url])
      except KeyError:
        # cache miss
        pass
      except Exception as e:
        logging.getLogger("Cover").warning("Unable to load metadata for URL '%s' from cache: %s %s" % (url,
                                                                                                       e.__class__.__qualname__,
                                                                                                       e))
      else:
        # cache hit
        logging.getLogger("Cover").debug("Got metadata for URL '%s' from cache" % (url))
        if format is not None:
          self.setFormatMetadata(format)

      if (self.needMetadataUpdate(CoverImageMetadata.FORMAT) or
              (self.needMetadataUpdate(CoverImageMetadata.SIZE) and ((width is None) or (height is None)))):
        # download
        logging.getLogger("Cover").debug("Downloading file header for URL '%s'..." % (url))
        try:
          headers = {}
          self.source.updateHttpHeaders(headers)
          response = await self.source.http.fastStreamedQuery(url,
                                                              headers=headers,
                                                              verify=False)
          try:
            if self.needMetadataUpdate(CoverImageMetadata.FORMAT):
              # try to get format from response
              format = __class__.guessImageFormatFromHttpResponse(response)
              if format is not None:
                self.setFormatMetadata(format)

            if self.needMetadataUpdate():
              # try to get metadata from HTTP data
              metadata = await __class__.guessImageMetadataFromHttpData(response)
              if metadata is not None:
                format, width, height = metadata
                if format is not None:
                  self.setFormatMetadata(format)

          finally:
            response.release()

        except Exception as e:
          logging.getLogger("Cover").warning("Failed to get file metadata for URL '%s' "
                                             "(%s %s)" % (url,
                                                          e.__class__.__qualname__,
                                                          e))

        if self.needMetadataUpdate():  # did we fail to get needed metadata at this point?
          if ((self.format is None) or
                  ((self.size is None) and ((width is None) or (height is None)))):
            # if we get here, file is probably not reachable, or not even an image
            logging.getLogger("Cover").debug("Unable to get file metadata from file or HTTP headers for URL '%s', "
                                             "skipping this result" % (url))
            return

          if ((self.format is not None) and
                  ((self.size is not None) and (width is None) and (height is None))):
            logging.getLogger("Cover").debug("Unable to get file metadata from file or HTTP headers for URL '%s', "
                                             "falling back to API data" % (url))
            self.check_metadata = CoverImageMetadata.NONE
            self.reliable_metadata = False
            return

        # save it to cache
        __class__.metadata_cache[url] = pickle.dumps((format, width, height))

      # sum sizes
      if (width is not None) and (height is not None):
        width_sum += width
        height_sum += height

    if self.needMetadataUpdate(CoverImageMetadata.SIZE) and (width_sum > 0) and (height_sum > 0):
      self.setSizeMetadata((width_sum, height_sum))
Partially download image file(s) to get its real metadata, or get it from cache.