From 75487055d8054e44496c7b3ff90e44c8fd8a78f6 Mon Sep 17 00:00:00 2001
From: Jared Moore <jared@moorejs.com>
Date: Wed, 27 Sep 2023 17:08:29 -0400
Subject: [PATCH 1/6] feat: add effort directive

---
 .changeset/rare-eels-refuse.md                |  5 ++
 docs/directives.md                            | 27 ++++++++-
 packages/core/src/index.ts                    |  1 +
 ...s-format-transform-png-w-effort-1-snap.png |  3 +
 ...-format-transform-webp-w-effort-1-snap.png |  3 +
 .../src/transforms/__tests__/effort.spec.ts   | 55 +++++++++++++++++++
 .../src/transforms/__tests__/format.spec.ts   | 12 ++++
 packages/core/src/transforms/effort.ts        | 16 ++++++
 packages/core/src/transforms/format.ts        |  2 +
 9 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 .changeset/rare-eels-refuse.md
 create mode 100644 packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png
 create mode 100644 packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png
 create mode 100644 packages/core/src/transforms/__tests__/effort.spec.ts
 create mode 100644 packages/core/src/transforms/effort.ts

diff --git a/.changeset/rare-eels-refuse.md b/.changeset/rare-eels-refuse.md
new file mode 100644
index 00000000..c95a51c7
--- /dev/null
+++ b/.changeset/rare-eels-refuse.md
@@ -0,0 +1,5 @@
+---
+'imagetools-core': minor
+---
+
+feat: add effort directive
diff --git a/docs/directives.md b/docs/directives.md
index f96b0fb4..1b9fef4b 100644
--- a/docs/directives.md
+++ b/docs/directives.md
@@ -5,6 +5,7 @@
 - [Directives](#directives)
   - [Background](#background)
   - [Blur](#blur)
+  - [Effort](#effort)
   - [Fit](#fit)
   - [Flatten](#flatten)
   - [Flip](#flip)
@@ -85,6 +86,30 @@ import Image from 'example.jpg?blur=100'
 
 ---
 
+### Effort
+
+• **Keyword**: `effort`<br> • **Type**: _integer_<br>
+
+Adjust the effort to spend encoding the image.
+The effect of effort varies per encoding, but a lower value leads to faster encoding.
+
+The supported range varies per encoding:
+- `png`: 1 to 10 (default 7)
+- `webp`: 0 to 6 (default 4)
+- `avif`/`heif`/`heic`: 0 to 9 (default 4)
+- `gif`: 1 to 10 (default 7)
+
+> Search `options.effort` in [sharp's Output options documentation](https://sharp.pixelplumbing.com/api-output) for details.
+
+• **Example**:
+
+```js
+import GenerateQuicklyWebp from 'example.jpg?format=webp&effort=1'
+import GenerateQuicklyAvif from 'example.jpg?format=avif&effort=0'
+```
+
+---
+
 ### Fit
 
 • **Keyword**: `fit`<br> • **Type**: _cover_ \| _contain_ \| _fill_ \| _inside_ \| _outside_ <br>
@@ -294,7 +319,7 @@ See sharps [resize options](https://sharp.pixelplumbing.com/api-resize#resize) f
 
 All formats (except `gif`) allow the quality to be adjusted by setting this directive.
 
-The argument must be a number between 0 and 100.
+The argument must be a number between 1 and 100.
 
 > See sharps [Output options](https://sharp.pixelplumbing.com/api-output) for default quality values.
 
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 55b1acaf..89b22bd6 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -1,5 +1,6 @@
 export * from './transforms/background.js'
 export * from './transforms/blur.js'
+export * from './transforms/effort.js'
 export * from './transforms/fit.js'
 export * from './transforms/flatten.js'
 export * from './transforms/flip.js'
diff --git a/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png
new file mode 100644
index 00000000..22923b0d
--- /dev/null
+++ b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:affc5551c29fa5fa062f068fc70e950c8c2743a68b1209737f4032ee4ba91d19
+size 187068
diff --git a/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png
new file mode 100644
index 00000000..1cafad7c
--- /dev/null
+++ b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6bcacda7957390d6d01c1a8d2787079802986909c4c84a761160fb2bbf3276f2
+size 11776
diff --git a/packages/core/src/transforms/__tests__/effort.spec.ts b/packages/core/src/transforms/__tests__/effort.spec.ts
new file mode 100644
index 00000000..622a8426
--- /dev/null
+++ b/packages/core/src/transforms/__tests__/effort.spec.ts
@@ -0,0 +1,55 @@
+import { getEffort } from '../effort'
+import sharp, { Sharp } from 'sharp'
+import { join } from 'path'
+import { describe, beforeEach, expect, test, it } from 'vitest'
+
+describe('effort', () => {
+  let img: Sharp
+  beforeEach(() => {
+    img = sharp(join(__dirname, '../../__tests__/__fixtures__/pexels-allec-gomes-5195763.png'))
+  })
+
+  test('keyword "effort"', () => {
+    const res = getEffort({ effort: '3' }, img)
+
+    expect(res).toEqual(3)
+  })
+
+  test('missing', () => {
+    const res = getEffort({}, img)
+
+    expect(res).toBeUndefined()
+  })
+
+  describe('arguments', () => {
+    test('invalid', () => {
+      const res = getEffort({ effort: 'invalid' }, img)
+
+      expect(res).toBeUndefined()
+    })
+
+    test('empty', () => {
+      const res = getEffort({ effort: '' }, img)
+
+      expect(res).toBeUndefined()
+    })
+
+    test('integer', () => {
+      const res = getEffort({ effort: '3' }, img)
+
+      expect(res).toEqual(3)
+    })
+
+    it('rounds float to int', () => {
+      const res = getEffort({ effort: '3.5' }, img)
+
+      expect(res).toEqual(3)
+    })
+
+    it('rounds float to int', () => {
+      const res = getEffort({ effort: '3.5' }, img)
+
+      expect(res).toEqual(3)
+    })
+  })
+})
diff --git a/packages/core/src/transforms/__tests__/format.spec.ts b/packages/core/src/transforms/__tests__/format.spec.ts
index 9ba3a1b3..027e9179 100644
--- a/packages/core/src/transforms/__tests__/format.spec.ts
+++ b/packages/core/src/transforms/__tests__/format.spec.ts
@@ -162,5 +162,17 @@ describe('format', () => {
 
       expect(await image.toBuffer()).toMatchFile()
     })
+
+    test('png w/ effort', async () => {
+      const { image } = await applyTransforms([format({ format: 'png', effort: '1' }, dirCtx)!], img)
+
+      expect(await image.toBuffer()).toMatchImageSnapshot()
+    })
+
+    test('webp w/ effort', async () => {
+      const { image } = await applyTransforms([format({ format: 'webp', effort: '0' }, dirCtx)!], img)
+
+      expect(await image.toBuffer()).toMatchImageSnapshot()
+    })
   })
 })
diff --git a/packages/core/src/transforms/effort.ts b/packages/core/src/transforms/effort.ts
new file mode 100644
index 00000000..9ab9f814
--- /dev/null
+++ b/packages/core/src/transforms/effort.ts
@@ -0,0 +1,16 @@
+import { TransformOption } from '../types.js'
+import { setMetadata } from '../lib/metadata.js'
+
+export interface EffortOptions {
+  effort: string
+}
+
+export const getEffort: TransformOption<EffortOptions, number> = ({ effort: _effort }, image) => {
+  const effort = _effort && parseInt(_effort)
+
+  if (!effort) return
+
+  setMetadata(image, 'effort', effort)
+
+  return effort
+}
diff --git a/packages/core/src/transforms/format.ts b/packages/core/src/transforms/format.ts
index 343f7cff..4890b0e3 100644
--- a/packages/core/src/transforms/format.ts
+++ b/packages/core/src/transforms/format.ts
@@ -1,5 +1,6 @@
 import { TransformFactory } from '../types.js'
 import { METADATA } from '../lib/metadata.js'
+import { getEffort } from './effort.js'
 import { getQuality } from './quality.js'
 import { getProgressive } from './progressive.js'
 import { getLossless } from './lossless.js'
@@ -22,6 +23,7 @@ export const format: TransformFactory<FormatOptions> = (config) => {
     image[METADATA].format = format
 
     return image.toFormat(format, {
+      effort: getEffort(config, image),
       quality: getQuality(config, image),
       lossless: getLossless(config, image) as boolean,
       progressive: getProgressive(config, image) as boolean

From 63dd7bb8f8ec922145be0d3fd9934495f600aa3d Mon Sep 17 00:00:00 2001
From: Jared Moore <jared@moorejs.com>
Date: Tue, 10 Oct 2023 09:55:58 -0400
Subject: [PATCH 2/6] feat: improve usability of effort (add min+max)

---
 docs/directives.md                            | 12 +++++----
 .../src/transforms/__tests__/effort.spec.ts   | 22 +++++++++++++---
 packages/core/src/transforms/effort.ts        | 26 ++++++++++++++++---
 3 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/docs/directives.md b/docs/directives.md
index 1b9fef4b..1e2ad1f6 100644
--- a/docs/directives.md
+++ b/docs/directives.md
@@ -88,24 +88,26 @@ import Image from 'example.jpg?blur=100'
 
 ### Effort
 
-• **Keyword**: `effort`<br> • **Type**: _integer_<br>
+• **Keyword**: `effort`<br> • **Type**: _integer_ | _"max"_ | _"min"_ <br>
 
 Adjust the effort to spend encoding the image.
-The effect of effort varies per encoding, but a lower value leads to faster encoding.
+The effect of effort varies per format, but a lower value leads to faster encoding.
 
-The supported range varies per encoding:
+The supported ranges by format:
 - `png`: 1 to 10 (default 7)
 - `webp`: 0 to 6 (default 4)
 - `avif`/`heif`/`heic`: 0 to 9 (default 4)
 - `gif`: 1 to 10 (default 7)
 
+The keywords `"min"` and `"max"` apply the highest effort value for the given image format.
+
 > Search `options.effort` in [sharp's Output options documentation](https://sharp.pixelplumbing.com/api-output) for details.
 
 • **Example**:
 
 ```js
-import GenerateQuicklyWebp from 'example.jpg?format=webp&effort=1'
-import GenerateQuicklyAvif from 'example.jpg?format=avif&effort=0'
+import highestEffortWebp from 'example.jpg?format=webp&effort=max'
+import quicklyGeneratingAvif from 'example.jpg?format=avif&effort=0'
 ```
 
 ---
diff --git a/packages/core/src/transforms/__tests__/effort.spec.ts b/packages/core/src/transforms/__tests__/effort.spec.ts
index 622a8426..c760145e 100644
--- a/packages/core/src/transforms/__tests__/effort.spec.ts
+++ b/packages/core/src/transforms/__tests__/effort.spec.ts
@@ -2,6 +2,7 @@ import { getEffort } from '../effort'
 import sharp, { Sharp } from 'sharp'
 import { join } from 'path'
 import { describe, beforeEach, expect, test, it } from 'vitest'
+import { METADATA } from '../../lib/metadata'
 
 describe('effort', () => {
   let img: Sharp
@@ -46,10 +47,25 @@ describe('effort', () => {
       expect(res).toEqual(3)
     })
 
-    it('rounds float to int', () => {
-      const res = getEffort({ effort: '3.5' }, img)
+    it('sets to minimum effort with "min"', async () => {
+      img[METADATA] = { format: 'webp' }
+      const res = getEffort({ effort: 'min' }, img)
 
-      expect(res).toEqual(3)
+      expect(res).toEqual(0)
+    })
+
+    it('sets to maximum effort with "max"', async () => {
+      img[METADATA] = { format: 'webp' }
+      const res = getEffort({ effort: 'max' }, img)
+
+      expect(res).toEqual(6)
+    })
+
+    it('ignores effort when not applicable', async () => {
+      img[METADATA] = { format: 'jpeg' }
+      const res = getEffort({ effort: 'max' }, img)
+
+      expect(res).toBeUndefined()
     })
   })
 })
diff --git a/packages/core/src/transforms/effort.ts b/packages/core/src/transforms/effort.ts
index 9ab9f814..950be180 100644
--- a/packages/core/src/transforms/effort.ts
+++ b/packages/core/src/transforms/effort.ts
@@ -1,14 +1,34 @@
 import { TransformOption } from '../types.js'
-import { setMetadata } from '../lib/metadata.js'
+import { getMetadata, setMetadata } from '../lib/metadata.js'
 
 export interface EffortOptions {
   effort: string
 }
 
+const FORMAT_TO_EFFORT_RANGE: Record<string, [number, number]> = {
+  png: [1, 10],
+  webp: [0, 6],
+  avif: [0, 9],
+  heif: [0, 9],
+  heic: [0, 9],
+  gif: [1, 10]
+}
+
+function parseEffort(effort: string, format: string) {
+  if (effort === 'min') {
+    return FORMAT_TO_EFFORT_RANGE[format]?.[0]
+  } else if (effort === 'max') {
+    return FORMAT_TO_EFFORT_RANGE[format]?.[1]
+  }
+  return parseInt(effort)
+}
+
 export const getEffort: TransformOption<EffortOptions, number> = ({ effort: _effort }, image) => {
-  const effort = _effort && parseInt(_effort)
+  if (!_effort) return
 
-  if (!effort) return
+  const format = (getMetadata(image, 'format') ?? '') as string
+  const effort = parseEffort(_effort, format)
+  if (!Number.isInteger(effort)) return
 
   setMetadata(image, 'effort', effort)
 

From 47b1693cb54d00312ff2ac6539331b8ec2e2fda3 Mon Sep 17 00:00:00 2001
From: Jared Moore <jared@moorejs.com>
Date: Tue, 10 Oct 2023 09:59:21 -0400
Subject: [PATCH 3/6] test(format): use effort keyword

---
 packages/core/src/transforms/__tests__/format.spec.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/core/src/transforms/__tests__/format.spec.ts b/packages/core/src/transforms/__tests__/format.spec.ts
index 027e9179..3c175c17 100644
--- a/packages/core/src/transforms/__tests__/format.spec.ts
+++ b/packages/core/src/transforms/__tests__/format.spec.ts
@@ -170,7 +170,7 @@ describe('format', () => {
     })
 
     test('webp w/ effort', async () => {
-      const { image } = await applyTransforms([format({ format: 'webp', effort: '0' }, dirCtx)!], img)
+      const { image } = await applyTransforms([format({ format: 'webp', effort: 'min' }, dirCtx)!], img)
 
       expect(await image.toBuffer()).toMatchImageSnapshot()
     })

From 7752c28640313564e4de4642f06447919f069dff Mon Sep 17 00:00:00 2001
From: Jared Moore <jared@moorejs.com>
Date: Tue, 10 Oct 2023 10:14:50 -0400
Subject: [PATCH 4/6] test(effort): update snapshot image

---
 ...s__-format.spec.ts---format---transform---webp-w--effort-1 | 3 +++
 ...ts-format-spec-ts-format-transform-png-w-effort-1-snap.png | 4 ++--
 ...s-format-spec-ts-format-transform-webp-w-effort-1-snap.png | 3 ---
 packages/core/src/transforms/__tests__/format.spec.ts         | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)
 create mode 100644 packages/core/src/transforms/__tests__/__file_snapshots__/src-transforms-__tests__-format.spec.ts---format---transform---webp-w--effort-1
 delete mode 100644 packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png

diff --git a/packages/core/src/transforms/__tests__/__file_snapshots__/src-transforms-__tests__-format.spec.ts---format---transform---webp-w--effort-1 b/packages/core/src/transforms/__tests__/__file_snapshots__/src-transforms-__tests__-format.spec.ts---format---transform---webp-w--effort-1
new file mode 100644
index 00000000..0ee6545b
--- /dev/null
+++ b/packages/core/src/transforms/__tests__/__file_snapshots__/src-transforms-__tests__-format.spec.ts---format---transform---webp-w--effort-1
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:edf97a52065e500d6d224e36222eb3083d691295643e550484c917e39136e0fb
+size 14920
diff --git a/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png
index 22923b0d..9fc902ea 100644
--- a/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png
+++ b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-png-w-effort-1-snap.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:affc5551c29fa5fa062f068fc70e950c8c2743a68b1209737f4032ee4ba91d19
-size 187068
+oid sha256:1cb50732d3aa1e40ba4745f9cf3156b18655b4550f808bf018459e28efd3cf59
+size 189976
diff --git a/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png b/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png
deleted file mode 100644
index 1cafad7c..00000000
--- a/packages/core/src/transforms/__tests__/__image_snapshots__/format-spec-ts-src-transforms-tests-format-spec-ts-format-transform-webp-w-effort-1-snap.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6bcacda7957390d6d01c1a8d2787079802986909c4c84a761160fb2bbf3276f2
-size 11776
diff --git a/packages/core/src/transforms/__tests__/format.spec.ts b/packages/core/src/transforms/__tests__/format.spec.ts
index 3c175c17..e73c695d 100644
--- a/packages/core/src/transforms/__tests__/format.spec.ts
+++ b/packages/core/src/transforms/__tests__/format.spec.ts
@@ -172,7 +172,7 @@ describe('format', () => {
     test('webp w/ effort', async () => {
       const { image } = await applyTransforms([format({ format: 'webp', effort: 'min' }, dirCtx)!], img)
 
-      expect(await image.toBuffer()).toMatchImageSnapshot()
+      expect(await image.toBuffer()).toMatchFile()
     })
   })
 })

From befee19bdd22bd0b2de4a30a8cbaa33afcad8993 Mon Sep 17 00:00:00 2001
From: Jared Moore <jared@moorejs.com>
Date: Wed, 1 Nov 2023 13:25:55 -0400
Subject: [PATCH 5/6] test: allow for higher difference threshold in PNG effort
 result

Covers platform difference between mac and linux (sharp#3783)
This pattern is already used elsewhere
---
 packages/core/src/transforms/__tests__/format.spec.ts | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/packages/core/src/transforms/__tests__/format.spec.ts b/packages/core/src/transforms/__tests__/format.spec.ts
index e73c695d..90c53dc3 100644
--- a/packages/core/src/transforms/__tests__/format.spec.ts
+++ b/packages/core/src/transforms/__tests__/format.spec.ts
@@ -166,7 +166,10 @@ describe('format', () => {
     test('png w/ effort', async () => {
       const { image } = await applyTransforms([format({ format: 'png', effort: '1' }, dirCtx)!], img)
 
-      expect(await image.toBuffer()).toMatchImageSnapshot()
+      expect(await image.toBuffer()).toMatchImageSnapshot({
+        failureThreshold: 0.05,
+        failureThresholdType: 'percent'
+      })
     })
 
     test('webp w/ effort', async () => {

From d57c5d76f4f0de384f03010be0012911bf6a1877 Mon Sep 17 00:00:00 2001
From: Jared Moore <jared@moorejs.com>
Date: Wed, 1 Nov 2023 16:06:40 -0400
Subject: [PATCH 6/6] add jxl, nix hiec

---
 docs/directives.md                     | 9 +++++----
 packages/core/src/transforms/effort.ts | 8 ++++----
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/docs/directives.md b/docs/directives.md
index 1e2ad1f6..6b0ee736 100644
--- a/docs/directives.md
+++ b/docs/directives.md
@@ -96,7 +96,8 @@ The effect of effort varies per format, but a lower value leads to faster encodi
 The supported ranges by format:
 - `png`: 1 to 10 (default 7)
 - `webp`: 0 to 6 (default 4)
-- `avif`/`heif`/`heic`: 0 to 9 (default 4)
+- `avif`/`heif`: 0 to 9 (default 4)
+- `jxl`: 3 to 9 (default 7)
 - `gif`: 1 to 10 (default 7)
 
 The keywords `"min"` and `"max"` apply the highest effort value for the given image format.
@@ -168,7 +169,7 @@ import Image from 'exmaple.jpg?flop=true'
 
 ### Format
 
-• **Keyword**: `format`<br> • **Type**: _heic_\| _heif_ \| _avif_ \| _jpeg_ \| _jpg_ \| _png_ \| _tiff_ \| _webp_ \|
+• **Keyword**: `format`<br> • **Type**: _jxl_\| _heif_ \| _avif_ \| _jpeg_ \| _jpg_ \| _png_ \| _tiff_ \| _webp_ \|
 _gif_<br>
 
 Convert the image into the given format.
@@ -180,7 +181,7 @@ Convert the image into the given format.
 
 ```js
 import Image from 'example.jpg?format=webp'
-import Images from 'example.jpg?format=webp;avif;heic'
+import Images from 'example.jpg?format=webp;avif;jxl'
 ```
 
 ---
@@ -259,7 +260,7 @@ Use this directive to set a different interpolation kernel when resizing the ima
 Use lossless compression mode.
 
 Formats that support this directive are: 
-  `avif`, `heif`, `heic`, and `webp`
+  `avif`, `heif`, `jxl`, and `webp`
 
 • **Example**:
 
diff --git a/packages/core/src/transforms/effort.ts b/packages/core/src/transforms/effort.ts
index 950be180..646e33fe 100644
--- a/packages/core/src/transforms/effort.ts
+++ b/packages/core/src/transforms/effort.ts
@@ -6,12 +6,12 @@ export interface EffortOptions {
 }
 
 const FORMAT_TO_EFFORT_RANGE: Record<string, [number, number]> = {
-  png: [1, 10],
-  webp: [0, 6],
   avif: [0, 9],
+  gif: [1, 10],
   heif: [0, 9],
-  heic: [0, 9],
-  gif: [1, 10]
+  jxl: [3, 9],
+  png: [1, 10],
+  webp: [0, 6]
 }
 
 function parseEffort(effort: string, format: string) {