1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2026-04-23 19:41:06 +02:00
Files
imgproxy/processing/colorspace_test.go
2026-04-15 17:52:28 +02:00

403 lines
11 KiB
Go

package processing_test
import (
"fmt"
"testing"
"github.com/imgproxy/imgproxy/v3/imagetype"
"github.com/imgproxy/imgproxy/v3/testutil"
"github.com/imgproxy/imgproxy/v3/vips"
"github.com/stretchr/testify/suite"
)
type ColorspaceTestSuite struct {
testSuite
}
var colorspaceTestOutSize = testSize{100, 100}
type colorspaceTestCase struct {
name string
sourceFile string
watermarkFile string
outFormat imagetype.Type
}
func (tc colorspaceTestCase) ImagePath() string {
return tc.sourceFile
}
func (tc colorspaceTestCase) URLOptions() string {
opts := fmt.Sprintf(
"resize:fill:%d:%d/enlarge:1/format:%s",
colorspaceTestOutSize.width,
colorspaceTestOutSize.height,
tc.outFormat,
)
if tc.watermarkFile != "" {
opts += "/watermark:0.5"
}
return opts
}
type preserveHDRTestCase struct {
name string
sourceFile string
outFormat imagetype.Type
preserveHDR bool // URL option value
}
func (tc preserveHDRTestCase) ImagePath() string {
return tc.sourceFile
}
func (tc preserveHDRTestCase) URLOptions() string {
return fmt.Sprintf(
"resize:fill:%d:%d/enlarge:1/format:%s/preserve_hdr:%t",
colorspaceTestOutSize.width,
colorspaceTestOutSize.height,
tc.outFormat,
tc.preserveHDR,
)
}
func (s *ColorspaceTestSuite) SetupSubTest() {
s.ResetLazyObjects()
}
func (s *ColorspaceTestSuite) runTestCase(tc testCase[colorspaceTestCase]) {
if tc.opts.watermarkFile != "" {
s.Config().WatermarkImage.Path = s.TestData.Path(tc.opts.watermarkFile)
}
s.processImageAndCheck(tc)
}
func (s *ColorspaceTestSuite) TestColorspace() {
testCases := []testCase[colorspaceTestCase]{
{
opts: colorspaceTestCase{
name: "8-bpp-png-srgb",
sourceFile: "test-images/png/8-bpp.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "16-bpp-png-rgb16",
sourceFile: "test-images/png/16-bpp.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
{
opts: colorspaceTestCase{
name: "16-bpp-png-jpeg-srgb",
sourceFile: "test-images/png/16-bpp.png",
outFormat: imagetype.JPEG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "8-bpp-tiff-srgb",
sourceFile: "test-images/tiff/8-bpp.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "16-bpp-tiff-rgb16",
sourceFile: "test-images/tiff/16-bpp.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
{
opts: colorspaceTestCase{
name: "8-bpp-grayscale-png-bw",
sourceFile: "test-images/png/8-bpp-grayscale.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationBW,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-png-grey16",
sourceFile: "test-images/png/16-bpp-grayscale.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationGrey16,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-png-jpeg-bw",
sourceFile: "test-images/png/16-bpp-grayscale.png",
outFormat: imagetype.JPEG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationBW,
},
{
opts: colorspaceTestCase{
name: "8-bpp-grayscale-tiff-bw",
sourceFile: "test-images/tiff/8-bpp-grayscale.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationBW,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-tiff-grey16",
sourceFile: "test-images/tiff/16-bpp-grayscale.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationGrey16,
},
}
for _, tc := range testCases {
s.Run(tc.opts.name, func() {
s.Config().Processing.PreserveHDR = true
s.runTestCase(tc)
})
}
}
func (s *ColorspaceTestSuite) TestLinearColorspace() {
testCases := []testCase[colorspaceTestCase]{
{
opts: colorspaceTestCase{
name: "16-bpp-linear-png-rgb16",
sourceFile: "test-images/png/16-bpp-linear.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
{
opts: colorspaceTestCase{
name: "32-bpp-linear-tiff-rgb16",
sourceFile: "test-images/tiff/32-bpp-linear.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
{
opts: colorspaceTestCase{
name: "16-bpp-linear-png-jpeg-srgb",
sourceFile: "test-images/png/16-bpp-linear.png",
outFormat: imagetype.JPEG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "8-bpp-png-jpeg-srgb",
sourceFile: "test-images/png/8-bpp.png",
outFormat: imagetype.JPEG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
}
for _, tc := range testCases {
s.Run(tc.opts.name+"_linear", func() {
s.ImageMatcher, _ = testutil.NewLazySuiteObj(s, func() (*testutil.ImageHashCacheMatcher, error) {
return testutil.NewImageHashCacheMatcher(s.TestData, testutil.HashTypeDct), nil
})
s.Config().Processing.PreserveHDR = true
s.Config().Processing.UseLinearColorspace = true
s.runTestCase(tc)
})
}
}
func (s *ColorspaceTestSuite) TestDownscaleHDR() {
testCases := []testCase[colorspaceTestCase]{
{
opts: colorspaceTestCase{
name: "16-bpp-png-srgb",
sourceFile: "test-images/png/16-bpp.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "16-bpp-tiff-srgb",
sourceFile: "test-images/tiff/16-bpp.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-png-bw",
sourceFile: "test-images/png/16-bpp-grayscale.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationBW,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-tiff-bw",
sourceFile: "test-images/tiff/16-bpp-grayscale.tiff",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationBW,
},
}
for _, tc := range testCases {
s.Run(tc.opts.name+"_no_preserve_hdr", func() {
s.Config().Processing.PreserveHDR = false
s.runTestCase(tc)
})
}
}
func (s *ColorspaceTestSuite) TestWatermarkColorspace() {
testCases := []testCase[colorspaceTestCase]{
{
opts: colorspaceTestCase{
name: "8-bpp-wm-16-bpp-srgb",
sourceFile: "test-images/png/8-bpp.png",
watermarkFile: "test-images/png/16-bpp.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "8-bpp-wm-16-bpp-grayscale-srgb",
sourceFile: "test-images/png/8-bpp.png",
watermarkFile: "test-images/png/16-bpp-grayscale.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
{
opts: colorspaceTestCase{
name: "8-bpp-grayscale-wm-16-bpp-grayscale-bw",
sourceFile: "test-images/png/8-bpp-grayscale.png",
watermarkFile: "test-images/png/16-bpp-grayscale.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationBW,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-wm-8-bpp-grayscale-grey16",
sourceFile: "test-images/png/16-bpp-grayscale.png",
watermarkFile: "test-images/png/8-bpp-grayscale.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationGrey16,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-wm-16-bpp-rgb16",
sourceFile: "test-images/png/16-bpp-grayscale.png",
watermarkFile: "test-images/png/16-bpp.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
{
opts: colorspaceTestCase{
name: "16-bpp-grayscale-wm-8-bpp-rgb16",
sourceFile: "test-images/png/16-bpp-grayscale.png",
watermarkFile: "test-images/png/8-bpp.png",
outFormat: imagetype.PNG,
},
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
}
for _, tc := range testCases {
s.Run(tc.opts.name, func() {
s.ImageMatcher, _ = testutil.NewLazySuiteObj(s, func() (*testutil.ImageHashCacheMatcher, error) {
return testutil.NewImageHashCacheMatcher(s.TestData, testutil.HashTypeDct), nil
})
s.Config().Processing.PreserveHDR = true
s.runTestCase(tc)
})
}
}
func (s *ColorspaceTestSuite) TestPreserveHDROptionOverride() {
testCases := []struct {
opts preserveHDRTestCase
configValue bool
outSize testSize
outInterpretation vips.Interpretation
}{
{
opts: preserveHDRTestCase{
name: "option-true-overrides-config-false",
sourceFile: "test-images/png/16-bpp.png",
outFormat: imagetype.PNG,
preserveHDR: true,
},
configValue: false,
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationRGB16,
},
{
opts: preserveHDRTestCase{
name: "option-false-overrides-config-true",
sourceFile: "test-images/png/16-bpp.png",
outFormat: imagetype.PNG,
preserveHDR: false,
},
configValue: true,
outSize: colorspaceTestOutSize,
outInterpretation: vips.InterpretationSRGB,
},
}
for _, tc := range testCases {
s.Run(tc.opts.name, func() {
s.Config().Processing.PreserveHDR = tc.configValue
testCase := testCase[preserveHDRTestCase]{
opts: tc.opts,
outSize: tc.outSize,
outInterpretation: tc.outInterpretation,
}
s.processImageAndCheck(testCase)
})
}
}
func TestColorspace(t *testing.T) {
suite.Run(t, new(ColorspaceTestSuite))
}