1
1
// Copyright (c) Six Labors.
2
2
// Licensed under the Six Labors Split License.
3
3
4
+ using System . Diagnostics . CodeAnalysis ;
4
5
using SixLabors . ImageSharp . Formats . Bmp ;
5
6
using SixLabors . ImageSharp . Formats . Png ;
6
7
using SixLabors . ImageSharp . IO ;
@@ -12,15 +13,12 @@ namespace SixLabors.ImageSharp.Formats.Icon;
12
13
internal abstract class IconDecoderCore ( DecoderOptions options ) : IImageDecoderInternals
13
14
{
14
15
private IconDir fileHeader ;
16
+ private IconDirEntry [ ] ? entries ;
15
17
16
18
public DecoderOptions Options { get ; } = options ;
17
19
18
20
public Size Dimensions { get ; private set ; }
19
21
20
- protected IconDir FileHeader { get => this . fileHeader ; private set => this . fileHeader = value ; }
21
-
22
- protected IconDirEntry [ ] Entries { get ; private set ; } = [ ] ;
23
-
24
22
public Image < TPixel > Decode < TPixel > ( BufferedReadStream stream , CancellationToken cancellationToken )
25
23
where TPixel : unmanaged, IPixel < TPixel >
26
24
{
@@ -30,11 +28,11 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
30
28
31
29
Span < byte > flag = stackalloc byte [ PngConstants . HeaderBytes . Length ] ;
32
30
33
- List < ( Image < TPixel > Image , IconFrameCompression Compression , int Index ) > decodedEntries = new ( this . Entries . Length ) ;
31
+ List < ( Image < TPixel > Image , IconFrameCompression Compression , int Index ) > decodedEntries = new ( this . entries . Length ) ;
34
32
35
- for ( int i = 0 ; i < this . Entries . Length ; i ++ )
33
+ for ( int i = 0 ; i < this . entries . Length ; i ++ )
36
34
{
37
- ref IconDirEntry entry = ref this . Entries [ i ] ;
35
+ ref IconDirEntry entry = ref this . entries [ i ] ;
38
36
39
37
// If we hit the end of the stream we should break.
40
38
if ( stream . Seek ( basePosition + entry . ImageOffset , SeekOrigin . Begin ) >= stream . Length )
@@ -90,7 +88,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
90
88
bitsPerPixel = x . Image . Metadata . GetBmpMetadata ( ) . BitsPerPixel ;
91
89
}
92
90
93
- this . SetFrameMetadata ( target . Metadata , this . Entries [ x . Index ] , x . Compression , bitsPerPixel ) ;
91
+ this . SetFrameMetadata ( target . Metadata , this . entries [ x . Index ] , x . Compression , bitsPerPixel ) ;
94
92
95
93
x . Image . Dispose ( ) ;
96
94
@@ -115,11 +113,11 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
115
113
Span < byte > flag = stackalloc byte [ PngConstants . HeaderBytes . Length ] ;
116
114
117
115
ImageMetadata metadata = new ( ) ;
118
- ImageFrameMetadata [ ] frames = new ImageFrameMetadata [ this . FileHeader . Count ] ;
116
+ ImageFrameMetadata [ ] frames = new ImageFrameMetadata [ this . fileHeader . Count ] ;
119
117
for ( int i = 0 ; i < frames . Length ; i ++ )
120
118
{
121
119
BmpBitsPerPixel bitsPerPixel = default ;
122
- ref IconDirEntry entry = ref this . Entries [ i ] ;
120
+ ref IconDirEntry entry = ref this . entries [ i ] ;
123
121
124
122
// If we hit the end of the stream we should break.
125
123
if ( stream . Seek ( basePosition + entry . ImageOffset , SeekOrigin . Begin ) >= stream . Length )
@@ -147,7 +145,7 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
147
145
bitsPerPixel = temp . Metadata . GetBmpMetadata ( ) . BitsPerPixel ;
148
146
}
149
147
150
- this . SetFrameMetadata ( frames [ i ] , this . Entries [ i ] , isPng ? IconFrameCompression . Png : IconFrameCompression . Bmp , bitsPerPixel ) ;
148
+ this . SetFrameMetadata ( frames [ i ] , this . entries [ i ] , isPng ? IconFrameCompression . Png : IconFrameCompression . Bmp , bitsPerPixel ) ;
151
149
152
150
// Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data
153
151
// which technically allows storing icons with larger than 256 pixels, but such larger sizes are not recommended by Microsoft.
@@ -159,6 +157,7 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
159
157
160
158
protected abstract void SetFrameMetadata ( ImageFrameMetadata metadata , in IconDirEntry entry , IconFrameCompression compression , BmpBitsPerPixel bitsPerPixel ) ;
161
159
160
+ [ MemberNotNull ( nameof ( entries ) ) ]
162
161
protected void ReadHeader ( Stream stream )
163
162
{
164
163
Span < byte > buffer = stackalloc byte [ IconDirEntry . Size ] ;
@@ -168,16 +167,16 @@ protected void ReadHeader(Stream stream)
168
167
this . fileHeader = IconDir . Parse ( buffer ) ;
169
168
170
169
// ICONDIRENTRY
171
- this . Entries = new IconDirEntry [ this . FileHeader . Count ] ;
172
- for ( int i = 0 ; i < this . Entries . Length ; i ++ )
170
+ this . entries = new IconDirEntry [ this . fileHeader . Count ] ;
171
+ for ( int i = 0 ; i < this . entries . Length ; i ++ )
173
172
{
174
173
_ = IconAssert . EndOfStream ( stream . Read ( buffer [ ..IconDirEntry . Size ] ) , IconDirEntry . Size ) ;
175
- this . Entries [ i ] = IconDirEntry . Parse ( buffer ) ;
174
+ this . entries [ i ] = IconDirEntry . Parse ( buffer ) ;
176
175
}
177
176
178
177
int width = 0 ;
179
178
int height = 0 ;
180
- foreach ( IconDirEntry entry in this . Entries )
179
+ foreach ( IconDirEntry entry in this . entries )
181
180
{
182
181
// Since Windows 95 size of an image in the ICONDIRENTRY structure might
183
182
// be set to zero, which means 256 pixels.
0 commit comments