66using System . Numerics ;
77using System . Runtime . CompilerServices ;
88using System . Runtime . InteropServices ;
9-
9+ using SixLabors . ImageSharp . ColorSpaces . Companding ;
1010using SixLabors . ImageSharp . Memory ;
1111using SixLabors . ImageSharp . PixelFormats ;
1212
@@ -70,25 +70,33 @@ protected PixelOperationsTests(ITestOutputHelper output)
7070
7171 internal static PixelOperations < TPixel > Operations => PixelOperations < TPixel > . Instance ;
7272
73- internal static TPixel [ ] CreateExpectedPixelData ( Vector4 [ ] source )
73+ internal static TPixel [ ] CreateExpectedPixelData ( Vector4 [ ] source , RefAction < Vector4 > vectorModifier = null )
7474 {
7575 var expected = new TPixel [ source . Length ] ;
7676
7777 for ( int i = 0 ; i < expected . Length ; i ++ )
7878 {
79- expected [ i ] . FromVector4 ( source [ i ] ) ;
79+ Vector4 v = source [ i ] ;
80+ vectorModifier ? . Invoke ( ref v ) ;
81+
82+ expected [ i ] . FromVector4 ( v ) ;
8083 }
84+
8185 return expected ;
8286 }
8387
84- internal static TPixel [ ] CreateScaledExpectedPixelData ( Vector4 [ ] source )
88+ internal static TPixel [ ] CreateScaledExpectedPixelData ( Vector4 [ ] source , RefAction < Vector4 > vectorModifier = null )
8589 {
8690 var expected = new TPixel [ source . Length ] ;
8791
8892 for ( int i = 0 ; i < expected . Length ; i ++ )
8993 {
90- expected [ i ] . FromScaledVector4 ( source [ i ] ) ;
94+ Vector4 v = source [ i ] ;
95+ vectorModifier ? . Invoke ( ref v ) ;
96+
97+ expected [ i ] . FromScaledVector4 ( v ) ;
9198 }
99+
92100 return expected ;
93101 }
94102
@@ -120,6 +128,112 @@ public void FromScaledVector4(int count)
120128 ) ;
121129 }
122130
131+ [ Theory ]
132+ [ MemberData ( nameof ( ArraySizesData ) ) ]
133+ public void FromCompandedScaledVector4 ( int count )
134+ {
135+ void sourceAction ( ref Vector4 v )
136+ {
137+ SRgbCompanding . Expand ( ref v ) ;
138+ }
139+
140+ void expectedAction ( ref Vector4 v )
141+ {
142+ SRgbCompanding . Compress ( ref v ) ;
143+ }
144+
145+ Vector4 [ ] source = CreateVector4TestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
146+ TPixel [ ] expected = CreateScaledExpectedPixelData ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
147+
148+ TestOperation (
149+ source ,
150+ expected ,
151+ ( s , d ) => Operations . FromVector4 ( this . Configuration , s , d . GetSpan ( ) , PixelConversionModifiers . SRgbCompand | PixelConversionModifiers . Scale )
152+ ) ;
153+ }
154+
155+ [ Theory ]
156+ [ MemberData ( nameof ( ArraySizesData ) ) ]
157+ public void FromPremultipliedVector4 ( int count )
158+ {
159+ void sourceAction ( ref Vector4 v )
160+ {
161+ Vector4Utils . Premultiply ( ref v ) ;
162+ }
163+
164+ void expectedAction ( ref Vector4 v )
165+ {
166+ Vector4Utils . UnPremultiply ( ref v ) ;
167+ }
168+
169+ Vector4 [ ] source = CreateVector4TestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
170+ TPixel [ ] expected = CreateExpectedPixelData ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
171+
172+ TestOperation (
173+ source ,
174+ expected ,
175+ ( s , d ) => Operations . FromVector4 ( this . Configuration , s , d . GetSpan ( ) , PixelConversionModifiers . Premultiply )
176+ ) ;
177+ }
178+
179+ [ Theory ]
180+ [ MemberData ( nameof ( ArraySizesData ) ) ]
181+ public void FromPremultipliedScaledVector4 ( int count )
182+ {
183+ void sourceAction ( ref Vector4 v )
184+ {
185+ Vector4Utils . Premultiply ( ref v ) ;
186+ }
187+
188+ void expectedAction ( ref Vector4 v )
189+ {
190+ Vector4Utils . UnPremultiply ( ref v ) ;
191+ }
192+
193+ Vector4 [ ] source = CreateVector4TestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
194+ TPixel [ ] expected = CreateScaledExpectedPixelData ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
195+
196+ TestOperation (
197+ source ,
198+ expected ,
199+ ( s , d ) => Operations . FromVector4 (
200+ this . Configuration ,
201+ s ,
202+ d . GetSpan ( ) ,
203+ PixelConversionModifiers . Premultiply | PixelConversionModifiers . Scale )
204+ ) ;
205+ }
206+
207+ [ Theory ]
208+ [ MemberData ( nameof ( ArraySizesData ) ) ]
209+ public void FromCompandedPremultipliedScaledVector4 ( int count )
210+ {
211+ void sourceAction ( ref Vector4 v )
212+ {
213+ SRgbCompanding . Expand ( ref v ) ;
214+ Vector4Utils . Premultiply ( ref v ) ;
215+ }
216+
217+ void expectedAction ( ref Vector4 v )
218+ {
219+ Vector4Utils . UnPremultiply ( ref v ) ;
220+ SRgbCompanding . Compress ( ref v ) ;
221+ }
222+
223+ Vector4 [ ] source = CreateVector4TestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
224+ TPixel [ ] expected = CreateScaledExpectedPixelData ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
225+
226+ TestOperation (
227+ source ,
228+ expected ,
229+ ( s , d ) => Operations . FromVector4 (
230+ this . Configuration ,
231+ s ,
232+ d . GetSpan ( ) ,
233+ PixelConversionModifiers . SRgbCompand | PixelConversionModifiers . Premultiply )
234+ ) ;
235+ }
236+
123237 [ Theory ]
124238 [ MemberData ( nameof ( ArraySizesData ) ) ]
125239 public void ToVector4 ( int count )
@@ -148,6 +262,115 @@ public void ToScaledVector4(int count)
148262 ) ;
149263 }
150264
265+ [ Theory ]
266+ [ MemberData ( nameof ( ArraySizesData ) ) ]
267+ public void ToCompandedScaledVector4 ( int count )
268+ {
269+ void sourceAction ( ref Vector4 v )
270+ {
271+ SRgbCompanding . Compress ( ref v ) ;
272+ }
273+
274+ void expectedAction ( ref Vector4 v )
275+ {
276+ SRgbCompanding . Expand ( ref v ) ;
277+ }
278+
279+ TPixel [ ] source = CreateScaledPixelTestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
280+ Vector4 [ ] expected = CreateExpectedScaledVector4Data ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
281+
282+ TestOperation (
283+ source ,
284+ expected ,
285+ ( s , d ) => Operations . ToVector4 (
286+ this . Configuration ,
287+ s ,
288+ d . GetSpan ( ) ,
289+ PixelConversionModifiers . SRgbCompand | PixelConversionModifiers . Scale )
290+ ) ;
291+ }
292+
293+ [ Theory ]
294+ [ MemberData ( nameof ( ArraySizesData ) ) ]
295+ public void ToPremultipliedVector4 ( int count )
296+ {
297+ void sourceAction ( ref Vector4 v )
298+ {
299+ Vector4Utils . UnPremultiply ( ref v ) ;
300+ }
301+
302+ void expectedAction ( ref Vector4 v )
303+ {
304+ Vector4Utils . Premultiply ( ref v ) ;
305+ }
306+
307+ TPixel [ ] source = CreatePixelTestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
308+ Vector4 [ ] expected = CreateExpectedVector4Data ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
309+
310+ TestOperation (
311+ source ,
312+ expected ,
313+ ( s , d ) => Operations . ToVector4 ( this . Configuration , s , d . GetSpan ( ) , PixelConversionModifiers . Premultiply )
314+ ) ;
315+ }
316+
317+ [ Theory ]
318+ [ MemberData ( nameof ( ArraySizesData ) ) ]
319+ public void ToPremultipliedScaledVector4 ( int count )
320+ {
321+ void sourceAction ( ref Vector4 v )
322+ {
323+ Vector4Utils . UnPremultiply ( ref v ) ;
324+ }
325+
326+ void expectedAction ( ref Vector4 v )
327+ {
328+ Vector4Utils . Premultiply ( ref v ) ;
329+ }
330+
331+ TPixel [ ] source = CreateScaledPixelTestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
332+ Vector4 [ ] expected = CreateExpectedScaledVector4Data ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
333+
334+ TestOperation (
335+ source ,
336+ expected ,
337+ ( s , d ) => Operations . ToVector4 (
338+ this . Configuration ,
339+ s ,
340+ d . GetSpan ( ) ,
341+ PixelConversionModifiers . Premultiply | PixelConversionModifiers . Scale ) ) ;
342+ }
343+
344+ [ Theory ]
345+ [ MemberData ( nameof ( ArraySizesData ) ) ]
346+ public void ToCompandedPremultipliedScaledVector4 ( int count )
347+ {
348+ void sourceAction ( ref Vector4 v )
349+ {
350+ Vector4Utils . UnPremultiply ( ref v ) ;
351+ SRgbCompanding . Compress ( ref v ) ;
352+ }
353+
354+ void expectedAction ( ref Vector4 v )
355+ {
356+ SRgbCompanding . Expand ( ref v ) ;
357+ Vector4Utils . Premultiply ( ref v ) ;
358+ }
359+
360+ TPixel [ ] source = CreateScaledPixelTestData ( count , ( ref Vector4 v ) => sourceAction ( ref v ) ) ;
361+ Vector4 [ ] expected = CreateExpectedScaledVector4Data ( source , ( ref Vector4 v ) => expectedAction ( ref v ) ) ;
362+
363+ TestOperation (
364+ source ,
365+ expected ,
366+ ( s , d ) => Operations . ToVector4 (
367+ this . Configuration ,
368+ s ,
369+ d . GetSpan ( ) ,
370+ PixelConversionModifiers . SRgbCompand | PixelConversionModifiers . Premultiply | PixelConversionModifiers . Scale )
371+ ) ;
372+ }
373+
151374 [ Theory ]
152375 [ MemberData ( nameof ( ArraySizesData ) ) ]
153376 public void FromArgb32Bytes ( int count )
@@ -477,25 +700,37 @@ public void ToRgba64Bytes(int count)
477700 ) ;
478701 }
479702
480- internal static Vector4 [ ] CreateExpectedVector4Data ( TPixel [ ] source )
703+ public delegate void RefAction < T1 > ( ref T1 arg1 ) ;
704+
705+ internal static Vector4 [ ] CreateExpectedVector4Data ( TPixel [ ] source , RefAction < Vector4 > vectorModifier = null )
481706 {
482707 var expected = new Vector4 [ source . Length ] ;
483708
484709 for ( int i = 0 ; i < expected . Length ; i ++ )
485710 {
486- expected [ i ] = source [ i ] . ToVector4 ( ) ;
711+ var v = source [ i ] . ToVector4 ( ) ;
712+
713+ vectorModifier ? . Invoke ( ref v ) ;
714+
715+ expected [ i ] = v ;
487716 }
717+
488718 return expected ;
489719 }
490720
491- internal static Vector4 [ ] CreateExpectedScaledVector4Data ( TPixel [ ] source )
721+ internal static Vector4 [ ] CreateExpectedScaledVector4Data ( TPixel [ ] source , RefAction < Vector4 > vectorModifier = null )
492722 {
493723 var expected = new Vector4 [ source . Length ] ;
494724
495725 for ( int i = 0 ; i < expected . Length ; i ++ )
496726 {
497- expected [ i ] = source [ i ] . ToScaledVector4 ( ) ;
727+ Vector4 v = source [ i ] . ToScaledVector4 ( ) ;
728+
729+ vectorModifier ? . Invoke ( ref v ) ;
730+
731+ expected [ i ] = v ;
498732 }
733+
499734 return expected ;
500735 }
501736
@@ -513,19 +748,22 @@ internal static void TestOperation<TSource, TDest>(
513748 }
514749 }
515750
516- internal static Vector4 [ ] CreateVector4TestData ( int length )
751+ internal static Vector4 [ ] CreateVector4TestData ( int length , RefAction < Vector4 > vectorModifier = null )
517752 {
518753 var result = new Vector4 [ length ] ;
519754 var rnd = new Random ( 42 ) ; // Deterministic random values
520755
521756 for ( int i = 0 ; i < result . Length ; i ++ )
522757 {
523- result [ i ] = GetVector ( rnd ) ;
758+ Vector4 v = GetVector ( rnd ) ;
759+ vectorModifier ? . Invoke ( ref v ) ;
760+
761+ result [ i ] = v ;
524762 }
525763 return result ;
526764 }
527765
528- internal static TPixel [ ] CreatePixelTestData ( int length )
766+ internal static TPixel [ ] CreatePixelTestData ( int length , RefAction < Vector4 > vectorModifier = null )
529767 {
530768 var result = new TPixel [ length ] ;
531769
@@ -534,13 +772,16 @@ internal static TPixel[] CreatePixelTestData(int length)
534772 for ( int i = 0 ; i < result . Length ; i ++ )
535773 {
536774 Vector4 v = GetVector ( rnd ) ;
775+
776+ vectorModifier ? . Invoke ( ref v ) ;
777+
537778 result [ i ] . FromVector4 ( v ) ;
538779 }
539780
540781 return result ;
541782 }
542783
543- internal static TPixel [ ] CreateScaledPixelTestData ( int length )
784+ internal static TPixel [ ] CreateScaledPixelTestData ( int length , RefAction < Vector4 > vectorModifier = null )
544785 {
545786 var result = new TPixel [ length ] ;
546787
@@ -549,6 +790,9 @@ internal static TPixel[] CreateScaledPixelTestData(int length)
549790 for ( int i = 0 ; i < result . Length ; i ++ )
550791 {
551792 Vector4 v = GetVector ( rnd ) ;
793+
794+ vectorModifier ? . Invoke ( ref v ) ;
795+
552796 result [ i ] . FromScaledVector4 ( v ) ;
553797 }
554798
0 commit comments