Skip to content

Commit 66f21f7

Browse files
Merge pull request #3108 from SixLabors/js/imageinfobytes
Add ImageInfo.GetPixelMemorySize; docs & tests
2 parents 703d1ba + c9f7e6e commit 66f21f7

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

src/ImageSharp/Formats/Gif/GifDecoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ private bool ReadFrame<TPixel>(
468468
int length = this.currentLocalColorTableSize = this.imageDescriptor.LocalColorTableSize * 3;
469469
this.currentLocalColorTable ??= this.configuration.MemoryAllocator.Allocate<byte>(768, AllocationOptions.Clean);
470470
stream.Read(this.currentLocalColorTable.GetSpan()[..length]);
471-
rawColorTable = this.currentLocalColorTable!.GetSpan()[..length];
471+
rawColorTable = this.currentLocalColorTable.GetSpan()[..length];
472472
}
473473
else if (this.globalColorTable != null)
474474
{

src/ImageSharp/ImageInfo.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ public ImageInfo(
6363
public int Height => this.Size.Height;
6464

6565
/// <summary>
66-
/// Gets the number of frames in the image.
66+
/// Gets the number of frame metadata entries available for the image.
6767
/// </summary>
68+
/// <remarks>
69+
/// This value is the same as <see cref="FrameMetadataCollection"/> count and may be <c>0</c> when frame
70+
/// metadata was not populated by the decoder.
71+
/// </remarks>
6872
public int FrameCount => this.FrameMetadataCollection.Count;
6973

7074
/// <summary>
@@ -73,8 +77,12 @@ public ImageInfo(
7377
public ImageMetadata Metadata { get; }
7478

7579
/// <summary>
76-
/// Gets the collection of metadata associated with individual image frames.
80+
/// Gets the metadata associated with the decoded image frames, if available.
7781
/// </summary>
82+
/// <remarks>
83+
/// For multi-frame formats, decoders populate one entry per decoded frame. For single-frame formats, this
84+
/// collection is typically empty.
85+
/// </remarks>
7886
public IReadOnlyList<ImageFrameMetadata> FrameMetadataCollection { get; }
7987

8088
/// <summary>
@@ -86,4 +94,24 @@ public ImageInfo(
8694
/// Gets the bounds of the image.
8795
/// </summary>
8896
public Rectangle Bounds => new(Point.Empty, this.Size);
97+
98+
/// <summary>
99+
/// Gets the total number of bytes required to store the image pixels in memory.
100+
/// </summary>
101+
/// <remarks>
102+
/// This reports the in-memory size of the pixel data represented by this <see cref="ImageInfo"/>, not the
103+
/// encoded size of the image file. The value is computed from the image dimensions and
104+
/// <see cref="PixelType"/>. When <see cref="FrameMetadataCollection"/> contains decoded frame metadata, the
105+
/// per-frame size is multiplied by that count. Otherwise, the value is the in-memory size of the single
106+
/// image frame represented by this <see cref="ImageInfo"/>.
107+
/// </remarks>
108+
/// <returns>The total number of bytes required to store the image pixels in memory.</returns>
109+
public long GetPixelMemorySize()
110+
{
111+
int count = this.FrameMetadataCollection.Count > 0
112+
? this.FrameMetadataCollection.Count
113+
: 1;
114+
115+
return (long)this.Size.Width * this.Size.Height * (this.PixelType.BitsPerPixel / 8) * count;
116+
}
89117
}

tests/ImageSharp.Tests/ImageInfoTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,34 @@ public void ImageInfoInitializesCorrectlyWithFrameMetadata()
5454
Assert.Equal(meta, info.Metadata);
5555
Assert.Equal(frameMetadata.Count, info.FrameMetadataCollection.Count);
5656
}
57+
58+
[Fact]
59+
public void GetPixelMemorySize_UsesSingleFrameWhenFrameMetadataIsEmpty()
60+
{
61+
const int width = 10;
62+
const int height = 20;
63+
64+
ImageMetadata meta = new() { DecodedImageFormat = PngFormat.Instance };
65+
meta.GetPngMetadata();
66+
67+
ImageInfo info = new(new Size(width, height), meta);
68+
69+
Assert.Equal(width * height * 4, info.GetPixelMemorySize());
70+
}
71+
72+
[Fact]
73+
public void GetPixelMemorySize_UsesFrameMetadataCountWhenAvailable()
74+
{
75+
const int width = 10;
76+
const int height = 20;
77+
IReadOnlyList<ImageFrameMetadata> frameMetadata = [new(), new(), new()];
78+
79+
ImageMetadata meta = new() { DecodedImageFormat = PngFormat.Instance };
80+
meta.GetPngMetadata();
81+
82+
ImageInfo info = new(new Size(width, height), meta, frameMetadata);
83+
84+
Assert.Equal(width * height * 4 * frameMetadata.Count, info.GetPixelMemorySize());
85+
}
86+
5787
}

0 commit comments

Comments
 (0)