1515 /// </summary>
1616 public abstract class ColorSpaceDetails
1717 {
18+ /// <summary>
19+ /// Is the color space a stencil indexed color space.
20+ /// <para>Stencil color spaces take care of inverting colors based on the Decode array.</para>
21+ /// </summary>
22+ public bool IsStencil { get ; }
23+
1824 /// <summary>
1925 /// The type of the ColorSpace.
2026 /// </summary>
@@ -39,10 +45,11 @@ public abstract class ColorSpaceDetails
3945 /// <summary>
4046 /// Create a new <see cref="ColorSpaceDetails"/>.
4147 /// </summary>
42- protected internal ColorSpaceDetails ( ColorSpace type )
48+ protected internal ColorSpaceDetails ( ColorSpace type , bool isStencil = false )
4349 {
4450 Type = type ;
4551 BaseType = type ;
52+ IsStencil = isStencil ;
4653 }
4754
4855 /// <summary>
@@ -279,7 +286,7 @@ public sealed class IndexedColorSpaceDetails : ColorSpaceDetails
279286 internal static ColorSpaceDetails Stencil ( ColorSpaceDetails colorSpaceDetails , double [ ] decode )
280287 {
281288 var blackIsOne = decode . Length >= 2 && decode [ 0 ] == 1 && decode [ 1 ] == 0 ;
282- return new IndexedColorSpaceDetails ( colorSpaceDetails , 1 , blackIsOne ? [ 255 , 0 ] : [ 0 , 255 ] ) ;
289+ return new IndexedColorSpaceDetails ( colorSpaceDetails , 1 , blackIsOne ? [ 255 , 0 ] : [ 0 , 255 ] , true ) ;
283290 }
284291
285292 /// <inheritdoc/>
@@ -310,11 +317,15 @@ internal static ColorSpaceDetails Stencil(ColorSpaceDetails colorSpaceDetails, d
310317 /// </summary>
311318 public ReadOnlySpan < byte > ColorTable => colorTable ;
312319
320+ public IndexedColorSpaceDetails ( ColorSpaceDetails baseColorSpaceDetails , byte hiVal , byte [ ] colorTable )
321+ : this ( baseColorSpaceDetails , hiVal , colorTable , false )
322+ { }
323+
313324 /// <summary>
314325 /// Create a new <see cref="IndexedColorSpaceDetails"/>.
315326 /// </summary>
316- public IndexedColorSpaceDetails ( ColorSpaceDetails baseColorSpaceDetails , byte hiVal , byte [ ] colorTable )
317- : base ( ColorSpace . Indexed )
327+ private IndexedColorSpaceDetails ( ColorSpaceDetails baseColorSpaceDetails , byte hiVal , byte [ ] colorTable , bool isStencil )
328+ : base ( ColorSpace . Indexed , isStencil )
318329 {
319330 BaseColorSpace = baseColorSpaceDetails ?? throw new ArgumentNullException ( nameof ( baseColorSpaceDetails ) ) ;
320331 HiVal = hiVal ;
@@ -367,56 +378,40 @@ internal Span<byte> UnwrapIndexedColorSpaceBytes(Span<byte> input)
367378 case ColorSpace . DeviceRGB :
368379 case ColorSpace . CalRGB :
369380 case ColorSpace . Lab :
370- {
371- Span < byte > result = new byte [ input . Length * 3 ] ;
372- var i = 0 ;
373- foreach ( var x in input )
374381 {
375- for ( var j = 0 ; j < 3 ; ++ j )
382+ Span < byte > result = new byte [ input . Length * 3 ] ;
383+ var i = 0 ;
384+ foreach ( var x in input )
376385 {
377- result [ i ++ ] = ColorTable [ x * 3 + j ] ;
386+ for ( var j = 0 ; j < 3 ; ++ j )
387+ {
388+ result [ i ++ ] = ColorTable [ x * 3 + j ] ;
389+ }
378390 }
379- }
380391
381- return result ;
382- }
392+ return result ;
393+ }
383394
384395 case ColorSpace . DeviceCMYK :
385- {
386- Span < byte > result = new byte [ input . Length * 4 ] ;
387- var i = 0 ;
388- foreach ( var x in input )
389396 {
390- for ( var j = 0 ; j < 4 ; ++ j )
397+ Span < byte > result = new byte [ input . Length * 4 ] ;
398+ var i = 0 ;
399+ foreach ( var x in input )
391400 {
392- result [ i ++ ] = ColorTable [ x * 4 + j ] ;
401+ for ( var j = 0 ; j < 4 ; ++ j )
402+ {
403+ result [ i ++ ] = ColorTable [ x * 4 + j ] ;
404+ }
393405 }
394- }
395406
396- return result ;
397- }
407+ return result ;
408+ }
398409
399410 case ColorSpace . DeviceGray :
400411 case ColorSpace . CalGray :
401412 case ColorSpace . Separation :
402- {
403- for ( var i = 0 ; i < input . Length ; ++ i )
404413 {
405- ref byte b = ref input [ i ] ;
406- b = ColorTable [ b ] ;
407- }
408-
409- return input ;
410- }
411-
412- case ColorSpace . DeviceN :
413- case ColorSpace . ICCBased :
414- {
415- int i = 0 ;
416- if ( BaseColorSpace . NumberOfColorComponents == 1 )
417- {
418- // In place
419- for ( i = 0 ; i < input . Length ; ++ i )
414+ for ( var i = 0 ; i < input . Length ; ++ i )
420415 {
421416 ref byte b = ref input [ i ] ;
422417 b = ColorTable [ b ] ;
@@ -425,17 +420,33 @@ internal Span<byte> UnwrapIndexedColorSpaceBytes(Span<byte> input)
425420 return input ;
426421 }
427422
428- Span < byte > result = new byte [ input . Length * BaseColorSpace . NumberOfColorComponents ] ;
429- foreach ( var x in input )
423+ case ColorSpace . DeviceN :
424+ case ColorSpace . ICCBased :
430425 {
431- for ( var j = 0 ; j < BaseColorSpace . NumberOfColorComponents ; ++ j )
426+ int i = 0 ;
427+ if ( BaseColorSpace . NumberOfColorComponents == 1 )
432428 {
433- result [ i ++ ] = ColorTable [ x * BaseColorSpace . NumberOfColorComponents + j ] ;
429+ // In place
430+ for ( i = 0 ; i < input . Length ; ++ i )
431+ {
432+ ref byte b = ref input [ i ] ;
433+ b = ColorTable [ b ] ;
434+ }
435+
436+ return input ;
434437 }
435- }
436438
437- return result ;
438- }
439+ Span < byte > result = new byte [ input . Length * BaseColorSpace . NumberOfColorComponents ] ;
440+ foreach ( var x in input )
441+ {
442+ for ( var j = 0 ; j < BaseColorSpace . NumberOfColorComponents ; ++ j )
443+ {
444+ result [ i ++ ] = ColorTable [ x * BaseColorSpace . NumberOfColorComponents + j ] ;
445+ }
446+ }
447+
448+ return result ;
449+ }
439450 }
440451
441452 return input ;
0 commit comments