function imagePreview(storage, createImagePreviews, previewSizes) {
  const defaultMaxSize = Math.max(...previewSizes)

  const test = entry => (entry.type === 'image' && isSupportedImage(entry)) || storage.hasFile(entry, rawPreviewSuffix)

  /**
   * @param {import('@home-gallery/types').TExtractorEntry} entry
   */
  const task = async (entry) => {
    const t0 = Date.now();
    let src
    let localEntry
    if (storage.hasFile(entry, rawPreviewSuffix)) {
      localEntry = await storage.createLocalFile(entry, rawPreviewSuffix)
      src = localEntry.file
    } else {
      src = await entry.getFile()
    }

    const size = getMaxImageSizeBy(entry.meta.rawPreviewExif) || getMaxImageSizeBy(entry.meta.exif) || defaultMaxSize
    const resizePreviewSizes = previewSizes.filter(s => s <= size)

    return createImagePreviews(entry, src, resizePreviewSizes)
      .then(createdSizes => {
        if (createdSizes.length > 0) {
          log.info(t0, `Created ${createdSizes.length} image previews from ${entry} with sizes of ${createdSizes.join(',')}`)
        }
      })
      .catch(err => {
        log.error(err, `Could not calculate image previews of ${entry}: ${err}`);
      })
      .finally(() => localEntry?.release())
  }

  return {
    test,
    task
  }
}
@param {import('@home-gallery/types').TStorage} storage
@param {ImagePreviewCreator} createImagePreviews
@param {number[]} previewSizes
@returns {import('stream').Transform}