88
99namespace PlateauResoniteLink . Application . Importing ;
1010
11- public enum RawTexturePayloadFormat
11+ public abstract class RawTexturePayload
1212{
13- Rgba32 = 0 ,
14- RgbaFloat32 = 1 ,
13+ private protected RawTexturePayload (
14+ int width ,
15+ int height ,
16+ string ? colorProfile ,
17+ byte [ ] bytes )
18+ {
19+ ArgumentOutOfRangeException . ThrowIfNegativeOrZero ( width ) ;
20+ ArgumentOutOfRangeException . ThrowIfNegativeOrZero ( height ) ;
21+ ArgumentNullException . ThrowIfNull ( bytes ) ;
22+
23+ Width = width ;
24+ Height = height ;
25+ ColorProfile = colorProfile ;
26+ Bytes = bytes ;
27+ }
28+
29+ public int Width { get ; }
30+
31+ public int Height { get ; }
32+
33+ public string ? ColorProfile { get ; }
34+
35+ public byte [ ] Bytes { get ; }
36+
37+ public abstract TResult Match < TResult > (
38+ Func < Rgba32RawTexturePayload , TResult > rgba32 ,
39+ Func < RgbaFloat32RawTexturePayload , TResult > rgbaFloat32 ) ;
1540}
1641
17- public sealed record RawTexturePayload (
18- int Width ,
19- int Height ,
20- string ? ColorProfile ,
21- byte [ ] Bytes ,
22- RawTexturePayloadFormat Format = RawTexturePayloadFormat . Rgba32 ) ;
42+ public sealed class Rgba32RawTexturePayload : RawTexturePayload
43+ {
44+ public Rgba32RawTexturePayload (
45+ int width ,
46+ int height ,
47+ string ? colorProfile ,
48+ byte [ ] bytes )
49+ : base ( width , height , colorProfile , bytes )
50+ {
51+ }
52+
53+ public override TResult Match < TResult > (
54+ Func < Rgba32RawTexturePayload , TResult > rgba32 ,
55+ Func < RgbaFloat32RawTexturePayload , TResult > rgbaFloat32 )
56+ {
57+ ArgumentNullException . ThrowIfNull ( rgba32 ) ;
58+ ArgumentNullException . ThrowIfNull ( rgbaFloat32 ) ;
59+ return rgba32 ( this ) ;
60+ }
61+ }
62+
63+ public sealed class RgbaFloat32RawTexturePayload : RawTexturePayload
64+ {
65+ public RgbaFloat32RawTexturePayload (
66+ int width ,
67+ int height ,
68+ string ? colorProfile ,
69+ byte [ ] bytes )
70+ : base ( width , height , colorProfile , bytes )
71+ {
72+ }
73+
74+ public override TResult Match < TResult > (
75+ Func < Rgba32RawTexturePayload , TResult > rgba32 ,
76+ Func < RgbaFloat32RawTexturePayload , TResult > rgbaFloat32 )
77+ {
78+ ArgumentNullException . ThrowIfNull ( rgba32 ) ;
79+ ArgumentNullException . ThrowIfNull ( rgbaFloat32 ) ;
80+ return rgbaFloat32 ( this ) ;
81+ }
82+ }
2383
2484public interface ITextureImportSource
2585{
@@ -32,9 +92,14 @@ public interface ITextureImportSource
3292 long ? EstimatedByteLength { get ; }
3393}
3494
35- internal interface IRawTexturePayloadSource : ITextureImportSource
95+ internal interface IRgba32RawTexturePayloadSource : ITextureImportSource
3696{
37- ValueTask < RawTexturePayload > MaterializeRawAsync ( CancellationToken cancellationToken ) ;
97+ ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async ( CancellationToken cancellationToken ) ;
98+ }
99+
100+ internal interface IRgbaFloat32RawTexturePayloadSource : ITextureImportSource
101+ {
102+ ValueTask < RgbaFloat32RawTexturePayload > MaterializeRgbaFloat32Async ( CancellationToken cancellationToken ) ;
38103}
39104
40105internal static class TextureImportSourceMaterializer
@@ -44,17 +109,50 @@ public static ValueTask<RawTexturePayload> MaterializeRawAsync(
44109 CancellationToken cancellationToken )
45110 {
46111 ArgumentNullException . ThrowIfNull ( source ) ;
47- if ( source is not IRawTexturePayloadSource rawSource )
112+ if ( source is IRgba32RawTexturePayloadSource rgba32Source )
113+ {
114+ return new ValueTask < RawTexturePayload > ( MaterializeRgba32AsRawAsync ( rgba32Source , cancellationToken ) ) ;
115+ }
116+
117+ if ( source is IRgbaFloat32RawTexturePayloadSource rgbaFloat32Source )
118+ {
119+ return new ValueTask < RawTexturePayload > ( MaterializeRgbaFloat32AsRawAsync ( rgbaFloat32Source , cancellationToken ) ) ;
120+ }
121+
122+ throw new InvalidOperationException (
123+ $ "Texture import source '{ source . GetType ( ) . Name } ' cannot materialize a raw texture payload.") ;
124+
125+ static async Task < RawTexturePayload > MaterializeRgba32AsRawAsync (
126+ IRgba32RawTexturePayloadSource source ,
127+ CancellationToken cancellationToken )
128+ {
129+ return await source . MaterializeRgba32Async ( cancellationToken ) ;
130+ }
131+
132+ static async Task < RawTexturePayload > MaterializeRgbaFloat32AsRawAsync (
133+ IRgbaFloat32RawTexturePayloadSource source ,
134+ CancellationToken cancellationToken )
135+ {
136+ return await source . MaterializeRgbaFloat32Async ( cancellationToken ) ;
137+ }
138+ }
139+
140+ public static ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async (
141+ ITextureImportSource source ,
142+ CancellationToken cancellationToken )
143+ {
144+ ArgumentNullException . ThrowIfNull ( source ) ;
145+ if ( source is not IRgba32RawTexturePayloadSource rgba32Source )
48146 {
49147 throw new InvalidOperationException (
50- $ "Texture import source '{ source . GetType ( ) . Name } ' cannot materialize a raw texture payload.") ;
148+ $ "Texture import source '{ source . GetType ( ) . Name } ' cannot materialize an RGBA32 texture payload.") ;
51149 }
52150
53- return rawSource . MaterializeRawAsync ( cancellationToken ) ;
151+ return rgba32Source . MaterializeRgba32Async ( cancellationToken ) ;
54152 }
55153}
56154
57- internal sealed class InMemoryRawTextureImportSource : IRawTexturePayloadSource
155+ internal sealed class InMemoryRawTextureImportSource : IRgba32RawTexturePayloadSource
58156{
59157 private readonly byte [ ] bytes ;
60158
@@ -88,18 +186,18 @@ public InMemoryRawTextureImportSource(
88186
89187 public long ? EstimatedByteLength => bytes . Length ;
90188
91- public ValueTask < RawTexturePayload > MaterializeRawAsync ( CancellationToken cancellationToken )
189+ public ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async ( CancellationToken cancellationToken )
92190 {
93191 cancellationToken . ThrowIfCancellationRequested ( ) ;
94- return ValueTask . FromResult ( new RawTexturePayload (
192+ return ValueTask . FromResult ( new Rgba32RawTexturePayload (
95193 Width ,
96194 Height ,
97195 ColorProfile ,
98196 ( byte [ ] ) bytes . Clone ( ) ) ) ;
99197 }
100198}
101199
102- internal sealed class InMemoryEncodedTextureImportSource : IRawTexturePayloadSource
200+ internal sealed class InMemoryEncodedTextureImportSource : IRgba32RawTexturePayloadSource
103201{
104202 private readonly byte [ ] bytes ;
105203
@@ -123,7 +221,7 @@ public InMemoryEncodedTextureImportSource(
123221
124222 public long ? EstimatedByteLength => bytes . Length ;
125223
126- public async ValueTask < RawTexturePayload > MaterializeRawAsync ( CancellationToken cancellationToken )
224+ public async ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async ( CancellationToken cancellationToken )
127225 {
128226 cancellationToken . ThrowIfCancellationRequested ( ) ;
129227 using MemoryStream stream = new ( bytes , writable : false ) ;
@@ -138,7 +236,7 @@ internal sealed class DatasetTextureImportSource(
138236 IPlateauDatasetContentSource datasetSource ,
139237 string relativePath ,
140238 string ? colorProfile ,
141- string identity ) : IRawTexturePayloadSource
239+ string identity ) : IRgba32RawTexturePayloadSource
142240{
143241 public string Identity { get ; } = identity ;
144242
@@ -150,7 +248,7 @@ internal sealed class DatasetTextureImportSource(
150248 ? lengthSource . TryGetFileLength ( relativePath )
151249 : null ;
152250
153- public async ValueTask < RawTexturePayload > MaterializeRawAsync ( CancellationToken cancellationToken )
251+ public async ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async ( CancellationToken cancellationToken )
154252 {
155253 await using Stream stream = await datasetSource . OpenReadAsync ( relativePath , cancellationToken ) ;
156254 using Image < Rgba32 > image = await Image . LoadAsync < Rgba32 > ( stream , cancellationToken ) ;
@@ -161,7 +259,7 @@ public async ValueTask<RawTexturePayload> MaterializeRawAsync(CancellationToken
161259internal sealed class FileTextureImportSource (
162260 string absolutePath ,
163261 string colorProfile ,
164- string identity ) : IRawTexturePayloadSource
262+ string identity ) : IRgba32RawTexturePayloadSource
165263{
166264 public string Identity { get ; } = identity ;
167265
@@ -188,19 +286,40 @@ public long? EstimatedByteLength
188286 }
189287 }
190288
191- public async ValueTask < RawTexturePayload > MaterializeRawAsync ( CancellationToken cancellationToken )
289+ public async ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async ( CancellationToken cancellationToken )
192290 {
193291 using Image < Rgba32 > image = await Image . LoadAsync < Rgba32 > ( absolutePath , cancellationToken ) ;
194292 return TextureImportSourceFactory . CreateRawPayloadFromImage ( image , ColorProfile ) ;
195293 }
196294}
197295
198- internal sealed class GeneratedTextureImportSource (
199- Func < CancellationToken , ValueTask < RawTexturePayload > > materializeRawAsync ,
296+ internal sealed class GeneratedRgba32TextureImportSource (
297+ Func < CancellationToken , ValueTask < Rgba32RawTexturePayload > > materializeRgba32Async ,
298+ string identity ,
299+ string description ,
300+ string ? colorProfile ,
301+ long ? estimatedByteLength = null ) : IRgba32RawTexturePayloadSource
302+ {
303+ public string Identity { get ; } = identity ;
304+
305+ public string Description { get ; } = description ;
306+
307+ public string ? ColorProfile { get ; } = colorProfile ;
308+
309+ public long ? EstimatedByteLength { get ; } = estimatedByteLength ;
310+
311+ public ValueTask < Rgba32RawTexturePayload > MaterializeRgba32Async ( CancellationToken cancellationToken )
312+ {
313+ return materializeRgba32Async ( cancellationToken ) ;
314+ }
315+ }
316+
317+ internal sealed class GeneratedRgbaFloat32TextureImportSource (
318+ Func < CancellationToken , ValueTask < RgbaFloat32RawTexturePayload > > materializeRgbaFloat32Async ,
200319 string identity ,
201320 string description ,
202321 string ? colorProfile ,
203- long ? estimatedByteLength = null ) : IRawTexturePayloadSource
322+ long ? estimatedByteLength = null ) : IRgbaFloat32RawTexturePayloadSource
204323{
205324 public string Identity { get ; } = identity ;
206325
@@ -210,9 +329,9 @@ internal sealed class GeneratedTextureImportSource(
210329
211330 public long ? EstimatedByteLength { get ; } = estimatedByteLength ;
212331
213- public ValueTask < RawTexturePayload > MaterializeRawAsync ( CancellationToken cancellationToken )
332+ public ValueTask < RgbaFloat32RawTexturePayload > MaterializeRgbaFloat32Async ( CancellationToken cancellationToken )
214333 {
215- return materializeRawAsync ( cancellationToken ) ;
334+ return materializeRgbaFloat32Async ( cancellationToken ) ;
216335 }
217336}
218337
@@ -266,15 +385,30 @@ public static ITextureImportSource CreateFileImage(
266385 identity ?? $ "file:{ Path . GetFullPath ( absolutePath ) } :{ colorProfile } ") ;
267386 }
268387
269- public static ITextureImportSource CreateGeneratedImage (
270- Func < CancellationToken , ValueTask < RawTexturePayload > > materializeRawAsync ,
388+ public static ITextureImportSource CreateGeneratedRgba32Image (
389+ Func < CancellationToken , ValueTask < Rgba32RawTexturePayload > > materializeRgba32Async ,
390+ string identity ,
391+ string description ,
392+ string ? colorProfile ,
393+ long ? estimatedByteLength = null )
394+ {
395+ return new GeneratedRgba32TextureImportSource (
396+ materializeRgba32Async ,
397+ identity ,
398+ description ,
399+ colorProfile ,
400+ estimatedByteLength ) ;
401+ }
402+
403+ public static ITextureImportSource CreateGeneratedRgbaFloat32Image (
404+ Func < CancellationToken , ValueTask < RgbaFloat32RawTexturePayload > > materializeRgbaFloat32Async ,
271405 string identity ,
272406 string description ,
273407 string ? colorProfile ,
274408 long ? estimatedByteLength = null )
275409 {
276- return new GeneratedTextureImportSource (
277- materializeRawAsync ,
410+ return new GeneratedRgbaFloat32TextureImportSource (
411+ materializeRgbaFloat32Async ,
278412 identity ,
279413 description ,
280414 colorProfile ,
@@ -290,7 +424,7 @@ public static ITextureImportSource CreateGeneratedImageFromClone(
290424 ArgumentNullException . ThrowIfNull ( image ) ;
291425 Image < Rgba32 > retainedImage = image . Clone ( ) ;
292426 object gate = new ( ) ;
293- return CreateGeneratedImage (
427+ return CreateGeneratedRgba32Image (
294428 cancellationToken =>
295429 {
296430 cancellationToken . ThrowIfCancellationRequested ( ) ;
@@ -305,14 +439,14 @@ public static ITextureImportSource CreateGeneratedImageFromClone(
305439 ( long ) image . Width * image . Height * 4 ) ;
306440 }
307441
308- public static RawTexturePayload CreateRawPayloadFromImage (
442+ public static Rgba32RawTexturePayload CreateRawPayloadFromImage (
309443 Image < Rgba32 > image ,
310444 string ? colorProfile )
311445 {
312446 ArgumentNullException . ThrowIfNull ( image ) ;
313447 byte [ ] rawBytes = new byte [ image . Width * image . Height * 4 ] ;
314448 image . CopyPixelDataTo ( rawBytes ) ;
315- return new RawTexturePayload (
449+ return new Rgba32RawTexturePayload (
316450 image . Width ,
317451 image . Height ,
318452 colorProfile ,
0 commit comments