Repository: owncloud/ocis
Pull request #8981 (2024-04-26 09:32:23)

[full-ci] fix: replace github.com/disintegration/imaging with github.com/kovidg…
…oyal/imaging

## Description
Fixes CVE-2023-36308 - https://github.com/advisories/GHSA-q7pp-wcgr-pffx

## How Has This Been Tested?
:robot: 

## Screenshots (if appropriate):
![image](https://github.com/owncloud/ocis/assets/1005065/028de4ce-53e7-4b51-ab4d-0cf68a7ae754)


## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [x] Code changes
- [ ] Unit tests added
- [ ] Acceptance tests added
- [ ] Documentation ticket raised: <link> 


update-docs[bot]: Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/ocis/blob/master/changelog/README.md) item based on your changes.


Patch:
diff --git a/changelog/unreleased/CVE-2023-36308.md b/changelog/unreleased/CVE-2023-36308.md
new file mode 100644
index 00000000000..a8abb032121
--- /dev/null
+++ b/changelog/unreleased/CVE-2023-36308.md
@@ -0,0 +1,7 @@
+Bugfix: Crash when processing crafted TIFF files
+
+Fix for a vulnerability with low severity in disintegration/imaging.
+
+https://github.com/advisories/GHSA-q7pp-wcgr-pffx
+https://github.com/owncloud/ocis/pull/8981
+
diff --git a/go.mod b/go.mod
index 0f041014db9..adce9e3311d 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,6 @@ require (
 	github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781
 	github.com/cs3org/reva/v2 v2.19.2-0.20240426071117-7ed0671f9e0b
 	github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
-	github.com/disintegration/imaging v1.6.2
 	github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
 	github.com/egirna/icap-client v0.1.1
 	github.com/gabriel-vasile/mimetype v1.4.3
@@ -56,6 +55,7 @@ require (
 	github.com/jellydator/ttlcache/v3 v3.2.0
 	github.com/jinzhu/now v1.1.5
 	github.com/justinas/alice v1.2.0
+	github.com/kovidgoyal/imaging v1.6.3
 	github.com/leonelquinteros/gotext v1.6.0
 	github.com/libregraph/idm v0.5.0
 	github.com/libregraph/lico v0.61.3-0.20240322112242-72cf9221d3a7
diff --git a/go.sum b/go.sum
index a03b980a11a..1916c2a9931 100644
--- a/go.sum
+++ b/go.sum
@@ -1056,8 +1056,6 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8
 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 h1:simG0vMYFvNriGhaaat7QVVkaVkXzvqcohaBoLZl9Hg=
 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25/go.mod h1:Z3Lomva4pyMWYezjMAU5QWRh0p1VvO4199OHlFnyKkM=
 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
-github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
-github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
 github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
 github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
@@ -1613,6 +1611,8 @@ github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXH
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kovidgoyal/imaging v1.6.3 h1:iNPpv7ygiaB/NOztc6APMT7yr9UwBS+rOZwIbAdtyY8=
+github.com/kovidgoyal/imaging v1.6.3/go.mod h1:sHvcLOOVhJuto2IoNdPLEqnAUoL5ZfHEF0PpNH+882g=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -2200,7 +2200,6 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
diff --git a/services/thumbnails/pkg/preprocessor/preprocessor.go b/services/thumbnails/pkg/preprocessor/preprocessor.go
index b8949dc953d..d8addd3a709 100644
--- a/services/thumbnails/pkg/preprocessor/preprocessor.go
+++ b/services/thumbnails/pkg/preprocessor/preprocessor.go
@@ -12,7 +12,7 @@ import (
 	"mime"
 	"strings"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 	"github.com/pkg/errors"
 	"golang.org/x/image/font"
 	"golang.org/x/image/font/opentype"
diff --git a/services/thumbnails/pkg/thumbnail/generator.go b/services/thumbnails/pkg/thumbnail/generator.go
index 64aa086dff6..80796ad7ce8 100644
--- a/services/thumbnails/pkg/thumbnail/generator.go
+++ b/services/thumbnails/pkg/thumbnail/generator.go
@@ -7,7 +7,7 @@ import (
 	"image/gif"
 	"strings"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 )
 
 // Generator generates a web friendly file version.
diff --git a/services/thumbnails/pkg/thumbnail/processor.go b/services/thumbnails/pkg/thumbnail/processor.go
index 3782fac4fce..59bbe3a6369 100644
--- a/services/thumbnails/pkg/thumbnail/processor.go
+++ b/services/thumbnails/pkg/thumbnail/processor.go
@@ -4,7 +4,7 @@ import (
 	"image"
 	"strings"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 )
 
 // Processor processes the thumbnail by applying different transformations to it.
@@ -13,7 +13,7 @@ type Processor interface {
 	Process(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA
 }
 
-// DefinableProcessor is the most simple processor, it holds a replaceable image converter function.
+// DefinableProcessor is the simplest processor, it holds a replaceable image converter function.
 type DefinableProcessor struct {
 	Slug      string
 	Converter func(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA
diff --git a/vendor/github.com/disintegration/imaging/.travis.yml b/vendor/github.com/disintegration/imaging/.travis.yml
deleted file mode 100644
index 7ae5e4b25a5..00000000000
--- a/vendor/github.com/disintegration/imaging/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: go
-go:
-  - "1.10.x"
-  - "1.11.x"
-  - "1.12.x"
-
-before_install:
-  - go get github.com/mattn/goveralls
-
-script:
-  - go test -v -race -cover
-  - $GOPATH/bin/goveralls -service=travis-ci
diff --git a/vendor/github.com/kovidgoyal/imaging/.gitignore b/vendor/github.com/kovidgoyal/imaging/.gitignore
new file mode 100644
index 00000000000..cde012322cd
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/.gitignore
@@ -0,0 +1,2 @@
+
+dist/
diff --git a/vendor/github.com/kovidgoyal/imaging/.goreleaser.yaml b/vendor/github.com/kovidgoyal/imaging/.goreleaser.yaml
new file mode 100644
index 00000000000..25c4966c466
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/.goreleaser.yaml
@@ -0,0 +1,41 @@
+# This is an example .goreleaser.yml file with some sensible defaults.
+# Make sure to check the documentation at https://goreleaser.com
+
+# The lines below are called `modelines`. See `:help modeline`
+# Feel free to remove those if you don't want/need to use them.
+# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
+# vim: set ts=2 sw=2 tw=0 fo=cnqoj
+
+version: 1
+
+before:
+  hooks:
+    # You may remove this if you don't use go modules.
+    - go mod tidy
+    # you may remove this if you don't need go generate
+    - go generate ./...
+
+builds:
+  - skip: true
+
+archives:
+  - format: tar.gz
+    # this name template makes the OS and Arch compatible with the results of `uname`.
+    name_template: >-
+      {{ .ProjectName }}_
+      {{- title .Os }}_
+      {{- if eq .Arch "amd64" }}x86_64
+      {{- else if eq .Arch "386" }}i386
+      {{- else }}{{ .Arch }}{{ end }}
+      {{- if .Arm }}v{{ .Arm }}{{ end }}
+    # use zip for windows archives
+    format_overrides:
+      - goos: windows
+        format: zip
+
+changelog:
+  sort: asc
+  filters:
+    exclude:
+      - "^docs:"
+      - "^test:"
diff --git a/vendor/github.com/disintegration/imaging/LICENSE b/vendor/github.com/kovidgoyal/imaging/LICENSE
similarity index 100%
rename from vendor/github.com/disintegration/imaging/LICENSE
rename to vendor/github.com/kovidgoyal/imaging/LICENSE
diff --git a/vendor/github.com/disintegration/imaging/README.md b/vendor/github.com/kovidgoyal/imaging/README.md
similarity index 88%
rename from vendor/github.com/disintegration/imaging/README.md
rename to vendor/github.com/kovidgoyal/imaging/README.md
index a1fd764d2c7..7ca37e40907 100644
--- a/vendor/github.com/disintegration/imaging/README.md
+++ b/vendor/github.com/kovidgoyal/imaging/README.md
@@ -1,226 +1,231 @@
-# Imaging
-
-[![GoDoc](https://godoc.org/github.com/disintegration/imaging?status.svg)](https://godoc.org/github.com/disintegration/imaging)
-[![Build Status](https://travis-ci.org/disintegration/imaging.svg?branch=master)](https://travis-ci.org/disintegration/imaging)
-[![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master&service=github)](https://coveralls.io/github/disintegration/imaging?branch=master)
-[![Go Report Card](https://goreportcard.com/badge/github.com/disintegration/imaging)](https://goreportcard.com/report/github.com/disintegration/imaging)
-
-Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
-
-All the image processing functions provided by the package accept any image type that implements `image.Image` interface
-as an input, and return a new image of `*image.NRGBA` type (32bit RGBA colors, non-premultiplied alpha).
-
-## Installation
-
-    go get -u github.com/disintegration/imaging
-
-## Documentation
-
-http://godoc.org/github.com/disintegration/imaging
-
-## Usage examples
-
-A few usage examples can be found below. See the documentation for the full list of supported functions.
-
-### Image resizing
-
-```go
-// Resize srcImage to size = 128x128px using the Lanczos filter.
-dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
-
-// Resize srcImage to width = 800px preserving the aspect ratio.
-dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
-
-// Scale down srcImage to fit the 800x600px bounding box.
-dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
-
-// Resize and crop the srcImage to fill the 100x100px area.
-dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
-```
-
-Imaging supports image resizing using various resampling filters. The most notable ones:
-- `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results.
-- `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results.
-- `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom.
-- `Linear` - Bilinear resampling filter, produces smooth output. Faster than cubic filters.
-- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
-- `NearestNeighbor` - Fastest resampling filter, no antialiasing.
-
-The full list of supported filters:  NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
-
-**Resampling filters comparison**
-
-Original image:
-
-![srcImage](testdata/branches.png)
-
-The same image resized from 600x400px to 150x100px using different resampling filters.
-From faster (lower quality) to slower (higher quality):
-
-Filter                    | Resize result
---------------------------|---------------------------------------------
-`imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png)
-`imaging.Linear`          | ![dstImage](testdata/out_resize_linear.png)
-`imaging.CatmullRom`      | ![dstImage](testdata/out_resize_catrom.png)
-`imaging.Lanczos`         | ![dstImage](testdata/out_resize_lanczos.png)
-
-
-### Gaussian Blur
-
-```go
-dstImage := imaging.Blur(srcImage, 0.5)
-```
-
-Sigma parameter allows to control the strength of the blurring effect.
-
-Original image                     | Sigma = 0.5                            | Sigma = 1.5
------------------------------------|----------------------------------------|---------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
-
-### Sharpening
-
-```go
-dstImage := imaging.Sharpen(srcImage, 0.5)
-```
-
-`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
-
-Original image                     | Sigma = 0.5                               | Sigma = 1.5
------------------------------------|-------------------------------------------|------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
-
-### Gamma correction
-
-```go
-dstImage := imaging.AdjustGamma(srcImage, 0.75)
-```
-
-Original image                     | Gamma = 0.75                             | Gamma = 1.25
------------------------------------|------------------------------------------|-----------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
-
-### Contrast adjustment
-
-```go
-dstImage := imaging.AdjustContrast(srcImage, 20)
-```
-
-Original image                     | Contrast = 15                              | Contrast = -15
------------------------------------|--------------------------------------------|-------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
-
-### Brightness adjustment
-
-```go
-dstImage := imaging.AdjustBrightness(srcImage, 20)
-```
-
-Original image                     | Brightness = 10                              | Brightness = -10
------------------------------------|----------------------------------------------|---------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
-
-### Saturation adjustment
-
-```go
-dstImage := imaging.AdjustSaturation(srcImage, 20)
-```
-
-Original image                     | Saturation = 30                              | Saturation = -30
------------------------------------|----------------------------------------------|---------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_saturation_p30.png) | ![dstImage](testdata/out_saturation_m30.png)
-
-## FAQ
-
-### Incorrect image orientation after processing (e.g. an image appears rotated after resizing)
-
-Most probably, the given image contains the EXIF orientation tag.
-The stadard `image/*` packages do not support loading and saving
-this kind of information. To fix the issue, try opening images with
-the `AutoOrientation` decode option. If this option is set to `true`,
-the image orientation is changed after decoding, according to the
-orientation tag (if present). Here's the example:
-
-```go
-img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
-```
-
-### What's the difference between `imaging` and `gift` packages?
-
-[imaging](https://github.com/disintegration/imaging)
-is designed to be a lightweight and simple image manipulation package.
-It provides basic image processing functions and a few helper functions
-such as `Open` and `Save`. It consistently returns *image.NRGBA image 
-type (8 bits per channel, RGBA).
-
-[gift](https://github.com/disintegration/gift)
-supports more advanced image processing, for example, sRGB/Linear color
-space conversions. It also supports different output image types
-(e.g. 16 bits per channel) and provides easy-to-use API for chaining
-multiple processing steps together.
-
-## Example code
-
-```go
-package main
-
-import (
-	"image"
-	"image/color"
-	"log"
-
-	"github.com/disintegration/imaging"
-)
-
-func main() {
-	// Open a test image.
-	src, err := imaging.Open("testdata/flowers.png")
-	if err != nil {
-		log.Fatalf("failed to open image: %v", err)
-	}
-
-	// Crop the original image to 300x300px size using the center anchor.
-	src = imaging.CropAnchor(src, 300, 300, imaging.Center)
-
-	// Resize the cropped image to width = 200px preserving the aspect ratio.
-	src = imaging.Resize(src, 200, 0, imaging.Lanczos)
-
-	// Create a blurred version of the image.
-	img1 := imaging.Blur(src, 5)
-
-	// Create a grayscale version of the image with higher contrast and sharpness.
-	img2 := imaging.Grayscale(src)
-	img2 = imaging.AdjustContrast(img2, 20)
-	img2 = imaging.Sharpen(img2, 2)
-
-	// Create an inverted version of the image.
-	img3 := imaging.Invert(src)
-
-	// Create an embossed version of the image using a convolution filter.
-	img4 := imaging.Convolve3x3(
-		src,
-		[9]float64{
-			-1, -1, 0,
-			-1, 1, 1,
-			0, 1, 1,
-		},
-		nil,
-	)
-
-	// Create a new image and paste the four produced images into it.
-	dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
-	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
-	dst = imaging.Paste(dst, img2, image.Pt(0, 200))
-	dst = imaging.Paste(dst, img3, image.Pt(200, 0))
-	dst = imaging.Paste(dst, img4, image.Pt(200, 200))
-
-	// Save the resulting image as JPEG.
-	err = imaging.Save(dst, "testdata/out_example.jpg")
-	if err != nil {
-		log.Fatalf("failed to save image: %v", err)
-	}
-}
-```
-
-Output:
-
-![dstImage](testdata/out_example.jpg)
+# Imaging
+
+Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
+
+All the image processing functions provided by the package accept any image type that implements `image.Image` interface
+as an input, and return a new image of `*image.NRGBA` type (32bit RGBA colors, non-premultiplied alpha).
+
+## Installation
+
+    go get -u github.com/kovidgoyal/imaging
+
+## Documentation
+
+https://pkg.go.dev/github.com/kovidgoyal/imaging
+
+## Usage examples
+
+A few usage examples can be found below. See the documentation for the full list of supported functions.
+
+### Image resizing
+
+```go
+// Resize srcImage to size = 128x128px using the Lanczos filter.
+dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
+
+// Resize srcImage to width = 800px preserving the aspect ratio.
+dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
+
+// Scale down srcImage to fit the 800x600px bounding box.
+dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
+
+// Resize and crop the srcImage to fill the 100x100px area.
+dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
+```
+
+Imaging supports image resizing using various resampling filters. The most notable ones:
+- `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results.
+- `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results.
+- `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom.
+- `Linear` - Bilinear resampling filter, produces smooth output. Faster than cubic filters.
+- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
+- `NearestNeighbor` - Fastest resampling filter, no antialiasing.
+
+The full list of supported filters:  NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
+
+**Resampling filters comparison**
+
+Original image:
+
+![srcImage](testdata/branches.png)
+
+The same image resized from 600x400px to 150x100px using different resampling filters.
+From faster (lower quality) to slower (higher quality):
+
+Filter                    | Resize result
+--------------------------|---------------------------------------------
+`imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png)
+`imaging.Linear`          | ![dstImage](testdata/out_resize_linear.png)
+`imaging.CatmullRom`      | ![dstImage](testdata/out_resize_catrom.png)
+`imaging.Lanczos`         | ![dstImage](testdata/out_resize_lanczos.png)
+
+
+### Gaussian Blur
+
+```go
+dstImage := imaging.Blur(srcImage, 0.5)
+```
+
+Sigma parameter allows to control the strength of the blurring effect.
+
+Original image                     | Sigma = 0.5                            | Sigma = 1.5
+-----------------------------------|----------------------------------------|---------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
+
+### Sharpening
+
+```go
+dstImage := imaging.Sharpen(srcImage, 0.5)
+```
+
+`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
+
+Original image                     | Sigma = 0.5                               | Sigma = 1.5
+-----------------------------------|-------------------------------------------|------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
+
+### Gamma correction
+
+```go
+dstImage := imaging.AdjustGamma(srcImage, 0.75)
+```
+
+Original image                     | Gamma = 0.75                             | Gamma = 1.25
+-----------------------------------|------------------------------------------|-----------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
+
+### Contrast adjustment
+
+```go
+dstImage := imaging.AdjustContrast(srcImage, 20)
+```
+
+Original image                     | Contrast = 15                              | Contrast = -15
+-----------------------------------|--------------------------------------------|-------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
+
+### Brightness adjustment
+
+```go
+dstImage := imaging.AdjustBrightness(srcImage, 20)
+```
+
+Original image                     | Brightness = 10                              | Brightness = -10
+-----------------------------------|----------------------------------------------|---------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
+
+### Saturation adjustment
+
+```go
+dstImage := imaging.AdjustSaturation(srcImage, 20)
+```
+
+Original image                     | Saturation = 30                              | Saturation = -30
+-----------------------------------|----------------------------------------------|---------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_saturation_p30.png) | ![dstImage](testdata/out_saturation_m30.png)
+
+### Hue adjustment
+
+```go
+dstImage := imaging.AdjustHue(srcImage, 20)
+```
+
+Original image                     | Hue = 60                                     | Hue = -60
+-----------------------------------|----------------------------------------------|---------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_hue_p60.png) | ![dstImage](testdata/out_hue_m60.png)
+
+## FAQ
+
+### Incorrect image orientation after processing (e.g. an image appears rotated after resizing)
+
+Most probably, the given image contains the EXIF orientation tag.
+The standard `image/*` packages do not support loading and saving
+this kind of information. To fix the issue, try opening images with
+the `AutoOrientation` decode option. If this option is set to `true`,
+the image orientation is changed after decoding, according to the
+orientation tag (if present). Here's the example:
+
+```go
+img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
+```
+
+### What's the difference between `imaging` and `gift` packages?
+
+[imaging](https://github.com/kovidgoyal/imaging)
+is designed to be a lightweight and simple image manipulation package.
+It provides basic image processing functions and a few helper functions
+such as `Open` and `Save`. It consistently returns *image.NRGBA image 
+type (8 bits per channel, RGBA).
+
+[gift](https://github.com/disintegration/gift)
+supports more advanced image processing, for example, sRGB/Linear color
+space conversions. It also supports different output image types
+(e.g. 16 bits per channel) and provides easy-to-use API for chaining
+multiple processing steps together.
+
+## Example code
+
+```go
+package main
+
+import (
+	"image"
+	"image/color"
+	"log"
+
+	"github.com/kovidgoyal/imaging"
+)
+
+func main() {
+	// Open a test image.
+	src, err := imaging.Open("testdata/flowers.png")
+	if err != nil {
+		log.Fatalf("failed to open image: %v", err)
+	}
+
+	// Crop the original image to 300x300px size using the center anchor.
+	src = imaging.CropAnchor(src, 300, 300, imaging.Center)
+
+	// Resize the cropped image to width = 200px preserving the aspect ratio.
+	src = imaging.Resize(src, 200, 0, imaging.Lanczos)
+
+	// Create a blurred version of the image.
+	img1 := imaging.Blur(src, 5)
+
+	// Create a grayscale version of the image with higher contrast and sharpness.
+	img2 := imaging.Grayscale(src)
+	img2 = imaging.AdjustContrast(img2, 20)
+	img2 = imaging.Sharpen(img2, 2)
+
+	// Create an inverted version of the image.
+	img3 := imaging.Invert(src)
+
+	// Create an embossed version of the image using a convolution filter.
+	img4 := imaging.Convolve3x3(
+		src,
+		[9]float64{
+			-1, -1, 0,
+			-1, 1, 1,
+			0, 1, 1,
+		},
+		nil,
+	)
+
+	// Create a new image and paste the four produced images into it.
+	dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
+	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
+	dst = imaging.Paste(dst, img2, image.Pt(0, 200))
+	dst = imaging.Paste(dst, img3, image.Pt(200, 0))
+	dst = imaging.Paste(dst, img4, image.Pt(200, 200))
+
+	// Save the resulting image as JPEG.
+	err = imaging.Save(dst, "testdata/out_example.jpg")
+	if err != nil {
+		log.Fatalf("failed to save image: %v", err)
+	}
+}
+```
+
+Output:
+
+![dstImage](testdata/out_example.jpg)
diff --git a/vendor/github.com/disintegration/imaging/adjust.go b/vendor/github.com/kovidgoyal/imaging/adjust.go
similarity index 86%
rename from vendor/github.com/disintegration/imaging/adjust.go
rename to vendor/github.com/kovidgoyal/imaging/adjust.go
index daaf1de860c..971aebc6fe2 100644
--- a/vendor/github.com/disintegration/imaging/adjust.go
+++ b/vendor/github.com/kovidgoyal/imaging/adjust.go
@@ -62,6 +62,10 @@ func Invert(img image.Image) *image.NRGBA {
 //  dstImage = imaging.AdjustSaturation(srcImage, -10) // Decrease image saturation by 10%.
 //
 func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA {
+	if percentage == 0 {
+		return Clone(img)
+	}
+
 	percentage = math.Min(math.Max(percentage, -100), 100)
 	multiplier := 1 + percentage/100
 
@@ -76,6 +80,34 @@ func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA {
 	})
 }
 
+// AdjustHue changes the hue of the image using the shift parameter (measured in degrees) and returns the adjusted image.
+// The shift = 0 (or 360 / -360 / etc.) gives the original image.
+// The shift = 180 (or -180) corresponds to a 180° degree rotation of the color wheel and thus gives the image with its hue inverted for each pixel.
+//
+// Examples:
+//  dstImage = imaging.AdjustHue(srcImage, 90) // Shift Hue by 90°.
+//  dstImage = imaging.AdjustHue(srcImage, -30) // Shift Hue by -30°.
+//
+func AdjustHue(img image.Image, shift float64) *image.NRGBA {
+	if math.Mod(shift, 360) == 0 {
+		return Clone(img)
+	}
+
+	summand := shift / 360
+
+	return AdjustFunc(img, func(c color.NRGBA) color.NRGBA {
+		h, s, l := rgbToHSL(c.R, c.G, c.B)
+		h += summand
+		h = math.Mod(h, 1)
+		//Adding 1 because Golang's Modulo function behaves differently to similar operators in most other languages.
+		if h < 0 {
+			h++
+		}
+		r, g, b := hslToRGB(h, s, l)
+		return color.NRGBA{r, g, b, c.A}
+	})
+}
+
 // AdjustContrast changes the contrast of the image using the percentage parameter and returns the adjusted image.
 // The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
 // The percentage = -100 gives solid gray image.
@@ -86,6 +118,10 @@ func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA {
 //	dstImage = imaging.AdjustContrast(srcImage, 20) // Increase image contrast by 20%.
 //
 func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
+	if percentage == 0 {
+		return Clone(img)
+	}
+
 	percentage = math.Min(math.Max(percentage, -100.0), 100.0)
 	lut := make([]uint8, 256)
 
@@ -114,6 +150,10 @@ func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
 //	dstImage = imaging.AdjustBrightness(srcImage, 10) // Increase image brightness by 10%.
 //
 func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
+	if percentage == 0 {
+		return Clone(img)
+	}
+
 	percentage = math.Min(math.Max(percentage, -100.0), 100.0)
 	lut := make([]uint8, 256)
 
@@ -134,6 +174,10 @@ func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
 //	dstImage = imaging.AdjustGamma(srcImage, 0.7)
 //
 func AdjustGamma(img image.Image, gamma float64) *image.NRGBA {
+	if gamma == 1 {
+		return Clone(img)
+	}
+
 	e := 1.0 / math.Max(gamma, 0.0001)
 	lut := make([]uint8, 256)
 
diff --git a/vendor/github.com/disintegration/imaging/convolution.go b/vendor/github.com/kovidgoyal/imaging/convolution.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/convolution.go
rename to vendor/github.com/kovidgoyal/imaging/convolution.go
diff --git a/vendor/github.com/disintegration/imaging/doc.go b/vendor/github.com/kovidgoyal/imaging/doc.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/doc.go
rename to vendor/github.com/kovidgoyal/imaging/doc.go
diff --git a/vendor/github.com/disintegration/imaging/effects.go b/vendor/github.com/kovidgoyal/imaging/effects.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/effects.go
rename to vendor/github.com/kovidgoyal/imaging/effects.go
diff --git a/vendor/github.com/disintegration/imaging/histogram.go b/vendor/github.com/kovidgoyal/imaging/histogram.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/histogram.go
rename to vendor/github.com/kovidgoyal/imaging/histogram.go
diff --git a/vendor/github.com/disintegration/imaging/io.go b/vendor/github.com/kovidgoyal/imaging/io.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/io.go
rename to vendor/github.com/kovidgoyal/imaging/io.go
diff --git a/vendor/github.com/kovidgoyal/imaging/publish.py b/vendor/github.com/kovidgoyal/imaging/publish.py
new file mode 100644
index 00000000000..3b0317bf4f6
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/publish.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
+
+import os
+import subprocess
+
+
+def run(*args: str):
+    cp = subprocess.run(args)
+    if cp.returncode != 0:
+        raise SystemExit(cp.returncode)
+
+
+def main():
+    version = input('Enter the version to publish: ')
+    try:
+        ans = input(f'Publish version \033[91m{version}\033[m (y/n): ')
+    except KeyboardInterrupt:
+        ans = 'n'
+    if ans.lower() != 'y':
+        return
+    os.environ['GITHUB_TOKEN'] = open(os.path.join(os.environ['PENV'], 'github-token')).read().strip()
+    run('git', 'tag', '-a', 'v' + version, '-m', f'version {version}')
+    run('git', 'push')
+    run('goreleaser', 'release')
+
+
+if __name__ == '__main__':
+    main()
diff --git a/vendor/github.com/disintegration/imaging/resize.go b/vendor/github.com/kovidgoyal/imaging/resize.go
similarity index 99%
rename from vendor/github.com/disintegration/imaging/resize.go
rename to vendor/github.com/kovidgoyal/imaging/resize.go
index 706435e3dce..963f40c4827 100644
--- a/vendor/github.com/disintegration/imaging/resize.go
+++ b/vendor/github.com/kovidgoyal/imaging/resize.go
@@ -87,6 +87,10 @@ func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NR
 		dstH = int(math.Max(1.0, math.Floor(tmpH+0.5)))
 	}
 
+	if srcW == dstW && srcH == dstH {
+		return Clone(img)
+	}
+
 	if filter.Support <= 0 {
 		// Nearest-neighbor special case.
 		return resizeNearest(img, dstW, dstH)
@@ -98,10 +102,8 @@ func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NR
 	if srcW != dstW {
 		return resizeHorizontal(img, dstW, filter)
 	}
-	if srcH != dstH {
-		return resizeVertical(img, dstH, filter)
-	}
-	return Clone(img)
+	return resizeVertical(img, dstH, filter)
+
 }
 
 func resizeHorizontal(img image.Image, width int, filter ResampleFilter) *image.NRGBA {
diff --git a/vendor/github.com/disintegration/imaging/scanner.go b/vendor/github.com/kovidgoyal/imaging/scanner.go
similarity index 98%
rename from vendor/github.com/disintegration/imaging/scanner.go
rename to vendor/github.com/kovidgoyal/imaging/scanner.go
index 37d92cef886..84de2fc90f2 100644
--- a/vendor/github.com/disintegration/imaging/scanner.go
+++ b/vendor/github.com/kovidgoyal/imaging/scanner.go
@@ -18,7 +18,7 @@ func newScanner(img image.Image) *scanner {
 		h:     img.Bounds().Dy(),
 	}
 	if img, ok := img.(*image.Paletted); ok {
-		s.palette = make([]color.NRGBA, len(img.Palette))
+		s.palette = make([]color.NRGBA, max(256, len(img.Palette)))
 		for i := 0; i < len(img.Palette); i++ {
 			s.palette[i] = color.NRGBAModel.Convert(img.Palette[i]).(color.NRGBA)
 		}
diff --git a/vendor/github.com/kovidgoyal/imaging/session.vim b/vendor/github.com/kovidgoyal/imaging/session.vim
new file mode 100644
index 00000000000..76924354f1f
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/session.vim
@@ -0,0 +1,2 @@
+" Empty for the moment
+
diff --git a/vendor/github.com/disintegration/imaging/tools.go b/vendor/github.com/kovidgoyal/imaging/tools.go
similarity index 98%
rename from vendor/github.com/disintegration/imaging/tools.go
rename to vendor/github.com/kovidgoyal/imaging/tools.go
index 0ec19a039cc..9591ebc5ae2 100644
--- a/vendor/github.com/disintegration/imaging/tools.go
+++ b/vendor/github.com/kovidgoyal/imaging/tools.go
@@ -96,6 +96,10 @@ func Crop(img image.Image, rect image.Rectangle) *image.NRGBA {
 	if r.Empty() {
 		return &image.NRGBA{}
 	}
+	if r.Eq(img.Bounds().Sub(img.Bounds().Min)) {
+		return Clone(img)
+	}
+
 	src := newScanner(img)
 	dst := image.NewNRGBA(image.Rect(0, 0, r.Dx(), r.Dy()))
 	rowSize := r.Dx() * 4
@@ -133,6 +137,10 @@ func Paste(background, img image.Image, pos image.Point) *image.NRGBA {
 	if interRect.Empty() {
 		return dst
 	}
+	if interRect.Eq(dst.Bounds()) {
+		return Clone(img)
+	}
+
 	src := newScanner(img)
 	parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
 		for y := range ys {
diff --git a/vendor/github.com/disintegration/imaging/transform.go b/vendor/github.com/kovidgoyal/imaging/transform.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/transform.go
rename to vendor/github.com/kovidgoyal/imaging/transform.go
diff --git a/vendor/github.com/disintegration/imaging/utils.go b/vendor/github.com/kovidgoyal/imaging/utils.go
similarity index 88%
rename from vendor/github.com/disintegration/imaging/utils.go
rename to vendor/github.com/kovidgoyal/imaging/utils.go
index 6c7af1a5188..f650c05bce1 100644
--- a/vendor/github.com/disintegration/imaging/utils.go
+++ b/vendor/github.com/kovidgoyal/imaging/utils.go
@@ -5,8 +5,17 @@ import (
 	"math"
 	"runtime"
 	"sync"
+	"sync/atomic"
 )
 
+var maxProcs int64
+
+// SetMaxProcs limits the number of concurrent processing goroutines to the given value.
+// A value <= 0 clears the limit.
+func SetMaxProcs(value int) {
+	atomic.StoreInt64(&maxProcs, int64(value))
+}
+
 // parallel processes the data in separate goroutines.
 func parallel(start, stop int, fn func(<-chan int)) {
 	count := stop - start
@@ -15,6 +24,10 @@ func parallel(start, stop int, fn func(<-chan int)) {
 	}
 
 	procs := runtime.GOMAXPROCS(0)
+	limit := int(atomic.LoadInt64(&maxProcs))
+	if procs > limit && limit > 0 {
+		procs = limit
+	}
 	if procs > count {
 		procs = count
 	}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 1f98cc72eec..ef35213dfac 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -758,9 +758,6 @@ github.com/dgryski/go-rendezvous
 # github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
 ## explicit; go 1.18
 github.com/dhowden/tag
-# github.com/disintegration/imaging v1.6.2
-## explicit
-github.com/disintegration/imaging
 # github.com/dlclark/regexp2 v1.4.0
 ## explicit
 github.com/dlclark/regexp2
@@ -1256,6 +1253,9 @@ github.com/klauspost/compress/s2
 # github.com/klauspost/cpuid/v2 v2.2.6
 ## explicit; go 1.15
 github.com/klauspost/cpuid/v2
+# github.com/kovidgoyal/imaging v1.6.3
+## explicit; go 1.21
+github.com/kovidgoyal/imaging
 # github.com/leodido/go-urn v1.4.0
 ## explicit; go 1.18
 github.com/leodido/go-urn


Test patch:
diff --git a/services/thumbnails/pkg/thumbnail/processor_test.go b/services/thumbnails/pkg/thumbnail/processor_test.go
index febda33b817..893931a8795 100644
--- a/services/thumbnails/pkg/thumbnail/processor_test.go
+++ b/services/thumbnails/pkg/thumbnail/processor_test.go
@@ -3,7 +3,7 @@ package thumbnail_test
 import (
 	"testing"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 	tAssert "github.com/stretchr/testify/assert"
 
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail"