Skip to content

Commit a48de63

Browse files
antonfirsovJimBobSquarePants
authored andcommitted
Introduce non-generic ImageFrameCollection (#941)
* temporarily disable target frameworks * drop DelegateProcessor * drop IImageProcessingContext<TPixel> * drop NamedColors<T> * drop ColorBuilder<T> * drop the *Base postfix for clean class hierarchies * adding basic skeletons * non-generic ImageFrameCollection API definition * non-generic ImageFrameCollection tests * cleanup + docs + more tests * implement ImageFrameCollection methods * tests for generic PixelOperations.To<TDest>() * experimental implementation * fix .ttinclude * generate generic From<TSourcePixel>(...) * fix RgbaVector <--> BT709 Gray pixel conversion * Gray8 and Gray16 using ConvertFromRgbaScaledVector4() by default * fixed all conversion tests * ConstructGif_FromDifferentPixelTypes * fix xmldoc and other StyelCop findings * re-enable all target frameworks * fix NonGenericAddFrame() and NonGenericInsertFrame() * fix remaining bugs
1 parent f9f7a56 commit a48de63

50 files changed

Lines changed: 1824 additions & 876 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
*.svg text eol=lf
5151
*.targets text eol=lf
5252
*.tt text eol=lf
53-
*.ttinclude text eol=lf
53+
*.ttinclude text eol=crlf
5454
*.txt text eol=lf
5555
*.vb text eol=lf
5656
*.yml text eol=lf

src/ImageSharp/Common/Helpers/ImageMaths.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ public static byte Get8BitBT709Luminance(byte r, byte g, byte b) =>
3636
public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) =>
3737
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F));
3838

39+
/// <summary>
40+
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
41+
/// </summary>
42+
/// <param name="r">The red component.</param>
43+
/// <param name="g">The green component.</param>
44+
/// <param name="b">The blue component.</param>
45+
/// <returns>The <see cref="ushort"/>.</returns>
46+
[MethodImpl(InliningOptions.ShortMethod)]
47+
public static ushort Get16BitBT709Luminance(float r, float g, float b) =>
48+
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F));
49+
3950
/// <summary>
4051
/// Scales a value from a 16 bit <see cref="ushort"/> to it's 8 bit <see cref="byte"/> equivalent.
4152
/// </summary>
@@ -379,4 +390,4 @@ int GetMaxX(ImageFrame<TPixel> pixels)
379390
return GetBoundingRectangle(topLeft, bottomRight);
380391
}
381392
}
382-
}
393+
}

src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
2121
/// (4) Packing <see cref="Image{TPixel}"/> pixels from the <see cref="Vector4"/> buffer. <br/>
2222
/// These operations are executed in <see cref="NumberOfPostProcessorSteps"/> steps.
2323
/// <see cref="PixelRowsPerStep"/> image rows are converted in one step,
24-
/// which means that size of the allocated memory is limited (does not depend on <see cref="ImageFrame{TPixel}.Height"/>).
24+
/// which means that size of the allocated memory is limited (does not depend on <see cref="ImageFrame.Height"/>).
2525
/// </summary>
2626
internal class JpegImagePostProcessor : IDisposable
2727
{
@@ -177,4 +177,4 @@ private void ConvertColorsInto<TPixel>(ImageFrame<TPixel> destination)
177177
}
178178
}
179179
}
180-
}
180+
}

src/ImageSharp/Image.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ internal Image(
5353
/// </summary>
5454
protected Configuration Configuration { get; }
5555

56+
/// <summary>
57+
/// Gets the <see cref="ImageFrameCollection"/> implementing the public <see cref="Frames"/> property.
58+
/// </summary>
59+
protected abstract ImageFrameCollection NonGenericFrameCollection { get; }
60+
5661
/// <inheritdoc/>
5762
public PixelTypeInfo PixelType { get; }
5863

@@ -65,6 +70,11 @@ internal Image(
6570
/// <inheritdoc/>
6671
public ImageMetadata Metadata { get; }
6772

73+
/// <summary>
74+
/// Gets the frames of the image as (non-generic) <see cref="ImageFrameCollection"/>.
75+
/// </summary>
76+
public ImageFrameCollection Frames => this.NonGenericFrameCollection;
77+
6878
/// <summary>
6979
/// Gets the pixel buffer.
7080
/// </summary>
@@ -137,4 +147,4 @@ public void Visit<TPixel>(Image<TPixel> image)
137147
}
138148
}
139149
}
140-
}
150+
}

src/ImageSharp/ImageFrame.LoadPixelData.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
namespace SixLabors.ImageSharp
1010
{
1111
/// <content>
12-
/// Adds static methods allowing the creation of new image from raw pixel data.
12+
/// Contains methods for loading raw pixel data.
1313
/// </content>
14-
internal static class ImageFrame
14+
public partial class ImageFrame
1515
{
1616
/// <summary>
1717
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given byte array in <typeparamref name="TPixel"/> format.
@@ -22,7 +22,7 @@ internal static class ImageFrame
2222
/// <param name="height">The height of the final image.</param>
2323
/// <typeparam name="TPixel">The pixel format.</typeparam>
2424
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
25-
public static ImageFrame<TPixel> LoadPixelData<TPixel>(Configuration configuration, ReadOnlySpan<byte> data, int width, int height)
25+
internal static ImageFrame<TPixel> LoadPixelData<TPixel>(Configuration configuration, ReadOnlySpan<byte> data, int width, int height)
2626
where TPixel : struct, IPixel<TPixel>
2727
=> LoadPixelData(configuration, MemoryMarshal.Cast<byte, TPixel>(data), width, height);
2828

@@ -35,7 +35,7 @@ public static ImageFrame<TPixel> LoadPixelData<TPixel>(Configuration configurati
3535
/// <param name="height">The height of the final image.</param>
3636
/// <typeparam name="TPixel">The pixel format.</typeparam>
3737
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
38-
public static ImageFrame<TPixel> LoadPixelData<TPixel>(Configuration configuration, ReadOnlySpan<TPixel> data, int width, int height)
38+
internal static ImageFrame<TPixel> LoadPixelData<TPixel>(Configuration configuration, ReadOnlySpan<TPixel> data, int width, int height)
3939
where TPixel : struct, IPixel<TPixel>
4040
{
4141
int count = width * height;
@@ -48,4 +48,4 @@ public static ImageFrame<TPixel> LoadPixelData<TPixel>(Configuration configurati
4848
return image;
4949
}
5050
}
51-
}
51+
}

src/ImageSharp/ImageFrame.cs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
6+
using SixLabors.ImageSharp.Metadata;
7+
using SixLabors.ImageSharp.PixelFormats;
8+
using SixLabors.Memory;
9+
using SixLabors.Primitives;
10+
11+
namespace SixLabors.ImageSharp
12+
{
13+
/// <summary>
14+
/// Represents a pixel-agnostic image frame containing all pixel data and <see cref="ImageFrameMetadata"/>.
15+
/// In case of animated formats like gif, it contains the single frame in a animation.
16+
/// In all other cases it is the only frame of the image.
17+
/// </summary>
18+
public abstract partial class ImageFrame : IDisposable
19+
{
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="ImageFrame"/> class.
22+
/// </summary>
23+
/// <param name="configuration">The <see cref="Configuration"/>.</param>
24+
/// <param name="width">The width.</param>
25+
/// <param name="height">The height.</param>
26+
/// <param name="metadata">The <see cref="ImageFrameMetadata"/>.</param>
27+
protected ImageFrame(Configuration configuration, int width, int height, ImageFrameMetadata metadata)
28+
{
29+
Guard.NotNull(configuration, nameof(configuration));
30+
Guard.NotNull(metadata, nameof(metadata));
31+
32+
this.Configuration = configuration;
33+
this.MemoryAllocator = configuration.MemoryAllocator;
34+
this.Width = width;
35+
this.Height = height;
36+
this.Metadata = metadata;
37+
}
38+
39+
/// <summary>
40+
/// Gets the <see cref="MemoryAllocator" /> to use for buffer allocations.
41+
/// </summary>
42+
public MemoryAllocator MemoryAllocator { get; }
43+
44+
/// <summary>
45+
/// Gets the <see cref="Configuration"/> instance associated with this <see cref="ImageFrame{TPixel}"/>.
46+
/// </summary>
47+
internal Configuration Configuration { get; }
48+
49+
/// <summary>
50+
/// Gets the width.
51+
/// </summary>
52+
public int Width { get; private set; }
53+
54+
/// <summary>
55+
/// Gets the height.
56+
/// </summary>
57+
public int Height { get; private set; }
58+
59+
/// <summary>
60+
/// Gets the metadata of the frame.
61+
/// </summary>
62+
public ImageFrameMetadata Metadata { get; }
63+
64+
/// <summary>
65+
/// Gets the size of the frame.
66+
/// </summary>
67+
/// <returns>The <see cref="Size"/></returns>
68+
public Size Size() => new Size(this.Width, this.Height);
69+
70+
/// <summary>
71+
/// Gets the bounds of the frame.
72+
/// </summary>
73+
/// <returns>The <see cref="Rectangle"/></returns>
74+
public Rectangle Bounds() => new Rectangle(0, 0, this.Width, this.Height);
75+
76+
/// <inheritdoc />
77+
public abstract void Dispose();
78+
79+
internal abstract void CopyPixelsTo<TDestinationPixel>(Span<TDestinationPixel> destination)
80+
where TDestinationPixel : struct, IPixel<TDestinationPixel>;
81+
82+
/// <summary>
83+
/// Updates the size of the image frame.
84+
/// </summary>
85+
internal void UpdateSize(Size size)
86+
{
87+
this.Width = size.Width;
88+
this.Height = size.Height;
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)