11// Copyright (c) Six Labors.
22// Licensed under the Six Labors Split License.
33
4+ using System . Diagnostics . CodeAnalysis ;
45using SixLabors . ImageSharp . Formats . Bmp ;
56using SixLabors . ImageSharp . Formats . Png ;
67using SixLabors . ImageSharp . IO ;
@@ -12,15 +13,12 @@ namespace SixLabors.ImageSharp.Formats.Icon;
1213internal abstract class IconDecoderCore ( DecoderOptions options ) : IImageDecoderInternals
1314{
1415 private IconDir fileHeader ;
16+ private IconDirEntry [ ] ? entries ;
1517
1618 public DecoderOptions Options { get ; } = options ;
1719
1820 public Size Dimensions { get ; private set ; }
1921
20- protected IconDir FileHeader { get => this . fileHeader ; private set => this . fileHeader = value ; }
21-
22- protected IconDirEntry [ ] Entries { get ; private set ; } = [ ] ;
23-
2422 public Image < TPixel > Decode < TPixel > ( BufferedReadStream stream , CancellationToken cancellationToken )
2523 where TPixel : unmanaged, IPixel < TPixel >
2624 {
@@ -30,11 +28,11 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
3028
3129 Span < byte > flag = stackalloc byte [ PngConstants . HeaderBytes . Length ] ;
3230
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 ) ;
3432
35- for ( int i = 0 ; i < this . Entries . Length ; i ++ )
33+ for ( int i = 0 ; i < this . entries . Length ; i ++ )
3634 {
37- ref IconDirEntry entry = ref this . Entries [ i ] ;
35+ ref IconDirEntry entry = ref this . entries [ i ] ;
3836
3937 // If we hit the end of the stream we should break.
4038 if ( stream . Seek ( basePosition + entry . ImageOffset , SeekOrigin . Begin ) >= stream . Length )
@@ -90,7 +88,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
9088 bitsPerPixel = x . Image . Metadata . GetBmpMetadata ( ) . BitsPerPixel ;
9189 }
9290
93- this . SetFrameMetadata ( target . Metadata , this . Entries [ x . Index ] , x . Compression , bitsPerPixel ) ;
91+ this . SetFrameMetadata ( target . Metadata , this . entries [ x . Index ] , x . Compression , bitsPerPixel ) ;
9492
9593 x . Image . Dispose ( ) ;
9694
@@ -115,11 +113,11 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
115113 Span < byte > flag = stackalloc byte [ PngConstants . HeaderBytes . Length ] ;
116114
117115 ImageMetadata metadata = new ( ) ;
118- ImageFrameMetadata [ ] frames = new ImageFrameMetadata [ this . FileHeader . Count ] ;
116+ ImageFrameMetadata [ ] frames = new ImageFrameMetadata [ this . fileHeader . Count ] ;
119117 for ( int i = 0 ; i < frames . Length ; i ++ )
120118 {
121119 BmpBitsPerPixel bitsPerPixel = default ;
122- ref IconDirEntry entry = ref this . Entries [ i ] ;
120+ ref IconDirEntry entry = ref this . entries [ i ] ;
123121
124122 // If we hit the end of the stream we should break.
125123 if ( stream . Seek ( basePosition + entry . ImageOffset , SeekOrigin . Begin ) >= stream . Length )
@@ -147,7 +145,7 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
147145 bitsPerPixel = temp . Metadata . GetBmpMetadata ( ) . BitsPerPixel ;
148146 }
149147
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 ) ;
151149
152150 // Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data
153151 // 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
159157
160158 protected abstract void SetFrameMetadata ( ImageFrameMetadata metadata , in IconDirEntry entry , IconFrameCompression compression , BmpBitsPerPixel bitsPerPixel ) ;
161159
160+ [ MemberNotNull ( nameof ( entries ) ) ]
162161 protected void ReadHeader ( Stream stream )
163162 {
164163 Span < byte > buffer = stackalloc byte [ IconDirEntry . Size ] ;
@@ -168,16 +167,16 @@ protected void ReadHeader(Stream stream)
168167 this . fileHeader = IconDir . Parse ( buffer ) ;
169168
170169 // 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 ++ )
173172 {
174173 _ = IconAssert . EndOfStream ( stream . Read ( buffer [ ..IconDirEntry . Size ] ) , IconDirEntry . Size ) ;
175- this . Entries [ i ] = IconDirEntry . Parse ( buffer ) ;
174+ this . entries [ i ] = IconDirEntry . Parse ( buffer ) ;
176175 }
177176
178177 int width = 0 ;
179178 int height = 0 ;
180- foreach ( IconDirEntry entry in this . Entries )
179+ foreach ( IconDirEntry entry in this . entries )
181180 {
182181 // Since Windows 95 size of an image in the ICONDIRENTRY structure might
183182 // be set to zero, which means 256 pixels.
0 commit comments